﻿using JX.Core;
using JX.Core.Entity;
using JX.Dapper;
using JX.Infrastructure;
using JX.Infrastructure.Common;
using JX.Infrastructure.Data;
using JX.Infrastructure.Field;
using JX.Infrastructure.Log;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace JX.Application
{
	/// <summary>
	/// 模型管理服务层接口实现类
	/// </summary>
	public partial class ModelsServiceAppDapper : ServiceAppDapper<ModelsEntity>,IModelsServiceAppDapper
	{
		#region 仓储接口
		private readonly IUnitOfWorkFactory _uowFactory;
		private readonly IUserGroupsServiceAppDapper _userGroupsServiceApp;
		private readonly IRolesServiceAppDapper _rolesServiceApp;
		private readonly INodesTemplateRepositoryDapper _nodesTemplateRepository;
		private readonly INodesModelTemplateRepositoryDapper _nodesModelTemplateRepository;
		private readonly IModelTemplatesRepositoryDapper _modelTemplatesRepository;
		private readonly IOrderItemRepositoryDapper _orderItemRepository;
		private readonly ICommonInfoRepositoryDapper _commonInfoRepository;
		private readonly IWorkRepositoryDapper _workRepository;
		private readonly IWorkCategorySettingRepositoryDapper _workCategorySettingRepository;
		private readonly ILogRepositoryDapper _LogRepository;
		/// <summary>
		/// 构造器注入
		/// </summary>
		public ModelsServiceAppDapper(IModelsRepositoryDapper repository,
			IUserGroupsServiceAppDapper userGroupsServiceApp,
			IRolesServiceAppDapper rolesServiceApp,
			INodesTemplateRepositoryDapper nodesTemplateRepository,
			INodesModelTemplateRepositoryDapper nodesModelTemplateRepository,
			IModelTemplatesRepositoryDapper modelTemplatesRepository,
			IOrderItemRepositoryDapper orderItemRepository,
			ICommonInfoRepositoryDapper commonInfoRepository,
			IWorkRepositoryDapper workRepository,
			IWorkCategorySettingRepositoryDapper workCategorySettingRepository,
			ILogRepositoryDapper logRepository,
			IUnitOfWorkFactory uowFactory) : base(repository)
		{
			m_repository = repository;
			_userGroupsServiceApp = userGroupsServiceApp;
			_rolesServiceApp = rolesServiceApp;
			_nodesTemplateRepository = nodesTemplateRepository;
			_nodesModelTemplateRepository = nodesModelTemplateRepository;
			_modelTemplatesRepository = modelTemplatesRepository;
			_orderItemRepository = orderItemRepository;
			_commonInfoRepository = commonInfoRepository;
			_workRepository = workRepository;
			_workCategorySettingRepository = workCategorySettingRepository;
			_LogRepository = logRepository;
			_uowFactory = uowFactory;
		}
		#endregion

		#region 是否存在数据
		/// <summary>
		/// 判断模型名是否存在
		/// </summary>
		/// <param name="modelName"></param>
		/// <returns></returns>
		public bool ModelNameExists(string modelName)
		{
			return IsExist(p => p.ModelName == modelName);
		}
		/// <summary>
		/// 判断模型的表名是否存在 
		/// </summary>
		/// <param name="tableName"></param>
		/// <returns></returns>
		public bool TableNameExists(string tableName)
		{
			return IsExist(p => p.TableName == tableName);
		}
		#endregion

		#region 得到实体类
		/// <summary>
		/// 从缓存中得到指定模型ID的模型
		/// </summary>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public ModelsEntity GetCacheModelById(int modelId)
		{
			var cacheModelList = GetCacheModelList();
			foreach (var item in cacheModelList)
			{
				if (item.ModelID == modelId)
				{
					return item;
				}
			}
			return new ModelsEntity();
		}
		/// <summary>
		/// 从缓存中获取指定表名的模型
		/// </summary>
		/// <param name="tableName"></param>
		/// <returns></returns>
		public ModelsEntity GetCacheModelByTableName(string tableName)
		{
			var cacheModelList = GetCacheModelList();
			foreach (var item in cacheModelList)
			{
				if (item.TableName == tableName)
				{
					return item;
				}
			}
			return new ModelsEntity();
		}
		/// <summary>
		/// 根据模型类型取得对应的第一条模型信息
		/// </summary>
		/// <param name="modelType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public ModelsEntity GetModelByModelType(ModelType modelType, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			Expression<Func<ModelsEntity, bool>> funcWhere = w => true;
			if (modelType != ModelType.None)
			{
				var enumValue = (int)modelType;
				funcWhere = funcWhere.And(p => p.ModelType == enumValue);
			}
			return Get(predicate: funcWhere, writeAndRead: writeAndRead);
		}
		#endregion

		#region 得到实体类列表
		/// <summary>
		/// 获取缓存中的模型列表。
		/// 1、从缓存中得到模型列表。
		/// 2、如果缓存中不存在，则从数据库中得到，并添加到缓存中。
		/// </summary>
		/// <returns></returns>
		public IList<ModelsEntity> GetCacheModelList()
		{
			IList<ModelsEntity> modelList = CacheHelper.CacheServiceProvider.Get<IList<ModelsEntity>>("CK_CommonModel_ModelList_All");
			if (modelList == null)
			{
				modelList = GetModelList(ModelType.None, ModelShowType.None);
				CacheHelper.CacheServiceProvider.AddOrUpdate("CK_CommonModel_ModelList_All", modelList, TimeSpan.FromHours(24),true);
			}
			return modelList;
		}
		/// <summary>
		/// 获取缓存的内容模型列表
		/// </summary>
		/// <param name="isContent">true：内容模型；false：商品模型；</param>
		/// <returns></returns>
		public IList<ModelsEntity> GetCacheModelByIsContent(bool isContent)
		{
			var cacheModelList = GetCacheModelList();
			var result = new List<ModelsEntity>();
			foreach (var info in cacheModelList)
			{
				if (isContent)
				{
					if (info.ModelType == (int)ModelType.Content)
					{
						result.Add(info);
					}
				}
				else if (info.ModelType == (int)ModelType.Shop)
				{
					result.Add(info);
				}
			}
			return result;
		}
		/// <summary>
		/// 获取节点对应的模型缓存列表
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public IList<ModelsEntity> GetCacheModelByNodeId(int nodeId)
		{
			IList<ModelsEntity> list = new List<ModelsEntity>();
			var modelIDByNodeID = _nodesModelTemplateRepository.GetAllData<NodesModelTemplateEntity,int?>(predicate: p => p.NodeID == nodeId,selector:p=>p.ModelID);
			foreach (int item in modelIDByNodeID)
			{
				list.Add(GetCacheModelById(item));
			}
			return list;
		}

		/// <summary>
		/// 获取模型列表
		/// </summary>
		/// <param name="modelType"></param>
		/// <param name="showType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<ModelsEntity> GetModelList(ModelType modelType, ModelShowType showType, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			Expression<Func<ModelsEntity, bool>> funcWhere = w => true;
			if(modelType != ModelType.None)
			{
				var enumValue = (int)modelType;
				funcWhere = funcWhere.And(p=>p.ModelType == enumValue);
			}
			switch (showType)
			{
				case ModelShowType.Enable:
					funcWhere = funcWhere.And(p => p.IsDisabled == false);
					break;
				case ModelShowType.Disable:
					funcWhere = funcWhere.And(p => p.IsDisabled == true);
					break;
			}
			var list = GetList(predicate: funcWhere,writeAndRead:writeAndRead).ToList();
			if(list==null)
			{
				list = new List<ModelsEntity>();
			}
			return list;
		}
		/// <summary>
		/// 获取商品模型列表
		/// </summary>
		/// <param name="showType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<ModelsEntity> GetShopModelList(ModelShowType showType, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return GetModelList(ModelType.Shop, showType, writeAndRead);
		}
		/// <summary>
		/// 获取内容模型列表
		/// </summary>
		/// <param name="showType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<ModelsEntity> GetContentModelList(ModelShowType showType, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return GetModelList(ModelType.Content, showType, writeAndRead);
		}
		/// <summary>
		/// 获取自定义表单模型列表
		/// </summary>
		/// <param name="showType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<ModelsEntity> GetCustomFormModelList(ModelShowType showType, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return GetModelList(ModelType.CustomForm, showType, writeAndRead);
		}
		#endregion

		#region 获取验证码字段
		/// <summary>
		/// 获取信息模型中用户前台发表信息是否开启验证码
		/// </summary>
		/// <param name="modelID"></param>
		/// <returns></returns>
		public bool GetISEnableVerificationCode(int modelID)
		{
			var info = CacheHelper.CacheServiceProvider.Get("CK_CommonModel_ModelInfo_ModelId_" + modelID) as ModelsEntity;
			if (info == null)
			{
				info = m_repository.Get(modelID);
				CacheHelper.CacheServiceProvider.AddOrUpdate("CK_CommonModel_ModelInfo_ModelId_" + modelID, info);
			}
			return info.IsVerificationCode;
		}
		/// <summary>
		/// 获取验证码字段
		/// </summary>
		/// <returns></returns>
		public FieldInfo GetValidateCode()
		{
			FieldInfo info = new FieldInfo();
			info.Id = "validateCode";
			info.FieldName = "ValidateCode";
			info.FieldAlias = "验证码";
			info.EnableNull = true;
			info.FieldLevel = 1;
			info.FieldType = FieldType.ValidateCodeType;
			info.EnableShowOnSearchForm = true;
			info.DefaultValue = "";
			info.Disabled = false;
			return info;
		}
		#endregion

		#region 联合查询：得到节点绑定的模型列表：表：Model,NodesModelTemplate
		/// <summary>
		/// 得到节点绑定的模型列表
		/// </summary>
		/// <param name="nodeId"></param>
		/// <param name="enable">是否启用（true：启用；false：禁用；）</param>
		/// <param name="modelTyp">模型类型</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public DataTable GetModelListByNodeId(int nodeId, bool enable = true, ModelType modelTyp = ModelType.Content, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return m_repository.GetModelListByNodeId(nodeId, enable, modelTyp, writeAndRead);
		}
		#endregion

		#region 添加
		/// <summary>
		/// 添加模型。
		/// 1、检查模型的表名是否存在，存在则返回失败。
		/// 2、如果主键没有赋值的话，会生成一个新的主键值。
		/// </summary>
		/// <param name="entity"></param>
		/// <returns></returns>
		public override bool Add(ModelsEntity entity)
		{
			if (TableNameExists(entity.TableName))
			{
				return false;
			}
			if(base.Add(entity))
			{
				ExeSQL(Query.GetAddTableSql(entity.TableName));
				RemoveCache();
				return true;
			}
			return false;
		}
		/// <summary>
		/// 添加模型。
		/// 1、检查模型的表名是否存在，存在则返回失败。
		/// 2、如果主键没有赋值的话，会生成一个新的主键值。
		/// </summary>
		/// <param name="entity"></param>
		/// <returns></returns>
		public override async Task<bool> AddAsync(ModelsEntity entity)
		{
			if (TableNameExists(entity.TableName))
			{
				return false;
			}
			if (await base.AddAsync(entity))
			{
				ExeSQL(Query.GetAddTableSql(entity.TableName));
				RemoveCache();
				return true;
			}
			return false;
		}
		/// <summary>
		/// 增加一条记录，返回新的ID号。需要有一个单一主键，并且开启有标识符属性。
		/// 1、检查模型的表名是否存在，存在则返回失败。
		/// 2、如果主键没有赋值的话，会生成一个新的主键值。
		/// </summary>
		/// <param name="entity"></param>
		/// <returns></returns>
		public override int Insert(ModelsEntity entity)
		{
			if (TableNameExists(entity.TableName))
			{
				return 0;
			}
			RemoveCache();
			int id = base.Insert(entity);
			if(id > 0)
			{
				ExeSQL(Query.GetAddTableSql(entity.TableName));
			}
			return id;
		}
		/// <summary>
		/// 增加一条记录，返回新的ID号。需要有一个单一主键，并且开启有标识符属性。
		/// 1、检查模型的表名是否存在，存在则返回失败。
		/// 2、如果主键没有赋值的话，会生成一个新的主键值。
		/// </summary>
		/// <param name="entity"></param>
		/// <returns></returns>
		public override async Task<int> InsertAsync(ModelsEntity entity)
		{
			if (TableNameExists(entity.TableName))
			{
				return 0;
			}
			RemoveCache();
			int id = await base.InsertAsync(entity);
			if (id > 0)
			{
				ExeSQL(Query.GetAddTableSql(entity.TableName));
			}
			return id;
		}

		/// <summary>
		/// 添加默认字段:为模型生成默认字段,返回xml片段形式的字符串
		/// </summary>
		/// <returns>xml片段形式的字符串</returns>
		public string AddDefaultField()
		{
			#region 字段属性数组
			//字段名（ID、FieldName）
			string[] strArray = new string[] {
				"NodeId","InfoId","SpecialId","Title",
				"IncludePic", "TitleFontColor", "TitleFontType", "IsShowCommentLink", "Status",
				"Elite", "Priority", "Hits", "DayHits", "WeekHits", "MonthHits", "UpdateTime",
				 "TemplateFile", "DefaultPicUrl"
			 };
			//字段别名（FieldAlias）
			string[] strArray2 = new string[] {
				"所属栏目", "所属其它栏目", "专题","标题",
				"标题前缀", "标题颜色", "标题字形", "显示“评论”链接", "状态",
				"推荐级", "优先级", "点击数", "日点击数", "周点击数", "月点击数", "更新时间",
				"内容页模板", "图片"
			 };
			//字段提示（Tips）
			string[] strArray3 = new string[] {
				"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
			 };
			//字段描述（Description）
			string[] strArray4 = new string[] {
				"", "如一篇文章同时属于多个栏目，在此选择即可！","", "",
				"", "", "", "列表显示时是否在标题旁显示“评论”链接", "审核状态",
				"注：数字越大推荐级别越高","注：数字越大优先级别越高", "", "", "", "", "更新时间",
				"内容页模板地址",  ""
			 };
			//默认值（DefaultValue）
			string[] strArray5 = new string[] {
				"", "", "", "",
				"", "", "","False", "0",
				"0", "0", "0", "0", "0", "0", "",
				"", ""
			 };
			FieldType[] typeArray = new FieldType[] {
				FieldType.NodeType, FieldType.InfoType, FieldType.SpecialType,FieldType.TitleType,
				FieldType.ListBoxType, FieldType.ColorType, FieldType.ListBoxType, FieldType.BoolType, FieldType.StatusType,
				FieldType.IntegerType, FieldType.IntegerType, FieldType.IntegerType, FieldType.IntegerType, FieldType.IntegerType, FieldType.IntegerType, FieldType.DateTimeType,
				FieldType.TemplateType,FieldType.PictureType
			 };
			#endregion

			#region 默认字段配置
			//所属节点
			Collection<string> collection33 = new Collection<string>();
			collection33.Add("");
			collection33.Add("");
			Collection<string> item = collection33;
			//所属其它节点
			Collection<string> collection35 = new Collection<string>();
			collection35.Add("");
			collection35.Add("");
			Collection<string> collection2 = collection35;
			//专题
			Collection<string> collection36 = new Collection<string>();
			collection36.Add("");
			collection36.Add("");
			Collection<string> collection3 = collection36;
			//标题
			Collection<string> collection20 = new Collection<string>();
			collection20.Add("255");
			collection20.Add("100%");
			collection20.Add("true");
			collection20.Add("False");
			Collection<string> collection4 = collection20;
			//标题前缀
			Collection<string> collection21 = new Collection<string>();
			collection21.Add("无|$$$[图文]|[图文]$$$[组图]|[组图]$$$[推荐]|[推荐]$$$[注意]|[注意]");
			collection21.Add("1");
			collection21.Add("False");
			collection21.Add("1");
			Collection<string> collection5 = collection21;
			//标题颜色
			Collection<string> collection22 = new Collection<string>();
			collection22.Add("");
			Collection<string> collection6 = collection22;
			//标题字形
			Collection<string> collection23 = new Collection<string>();
			collection23.Add("字形$$$粗体$$$斜体$$$粗+斜$$$规则");
			collection23.Add("1");
			collection23.Add("False");
			collection21.Add("1");
			Collection<string> collection7 = collection23;
			//显示“评论”链接
			Collection<string> collection24 = new Collection<string>();
			collection24.Add("是");
			collection24.Add("否");
			Collection<string> collection8 = collection24;
			//状态
			Collection<string> collection25 = new Collection<string>();
			collection25.Add("0");
			collection25.Add("100");
			collection25.Add("-1");
			collection25.Add("0");
			Collection<string> collection9 = collection25;
			//推荐级别
			Collection<string> collection26 = new Collection<string>();
			collection26.Add("0");
			collection26.Add("100");
			collection26.Add("false");
			Collection<string> collection10 = collection26;
			//优先级
			Collection<string> collection27 = new Collection<string>();
			collection27.Add("0");
			collection27.Add("100");
			collection27.Add("false");
			Collection<string> collection11 = collection27;
			//点击数
			Collection<string> collection28 = new Collection<string>();
			collection28.Add("0");
			collection28.Add("");
			collection28.Add("false");
			Collection<string> collection12 = collection28;
			//日点击数
			Collection<string> collection29 = new Collection<string>();
			collection29.Add("0");
			collection29.Add("");
			collection29.Add("false");
			Collection<string> collection13 = collection29;
			//周点击数
			Collection<string> collection30 = new Collection<string>();
			collection30.Add("0");
			collection30.Add("");
			collection30.Add("false");
			Collection<string> collection14 = collection30;
			//月点击数
			Collection<string> collection31 = new Collection<string>();
			collection31.Add("0");
			collection31.Add("");
			collection31.Add("false");
			Collection<string> collection15 = collection31;
			//更新时间
			Collection<string> collection32 = new Collection<string>();
			collection32.Add("datetime");
			collection32.Add("1");
			collection32.Add("false");
			Collection<string> collection16 = collection32;
			//内容页模板
			Collection<string> collection34 = new Collection<string>();
			collection34.Add("");
			collection34.Add("");
			collection34.Add("");
			collection34.Add("");
			Collection<string> collection17 = collection34;
			//首页图片
			Collection<string> collection37 = new Collection<string>();
			collection37.Add("100%");
			collection37.Add("10240");
			collection37.Add("jpg|gif|bmp|png");
			collection37.Add("False");
			collection37.Add("False");
			collection37.Add("False");
			collection37.Add("true");
			collection37.Add("False");
			collection37.Add("{$Random}");
			Collection<string> collection18 = collection37;

			//把设置加入数组中
			Collection<Collection<string>> collection38 = new Collection<Collection<string>>();
			collection38.Add(item);
			collection38.Add(collection2);
			collection38.Add(collection3);
			collection38.Add(collection4);
			collection38.Add(collection5);
			collection38.Add(collection6);
			collection38.Add(collection7);
			collection38.Add(collection8);
			collection38.Add(collection9);
			collection38.Add(collection10);
			collection38.Add(collection11);
			collection38.Add(collection12);
			collection38.Add(collection13);
			collection38.Add(collection14);
			collection38.Add(collection15);
			collection38.Add(collection16);
			collection38.Add(collection17);
			collection38.Add(collection18);
			Collection<Collection<string>> collection19 = collection38;
			#endregion

			#region 把字段实体加入列表中
			IList<FieldInfo> fieldList = new List<FieldInfo>();
			for (int i = 0; i < 18; i++)
			{
				FieldInfo info = new FieldInfo();
				info.Id = strArray[i];
				info.FieldName = strArray[i];
				info.FieldAlias = strArray2[i];
				info.FieldType = typeArray[i];
				info.FieldLevel = 0;
				info.Tips = strArray3[i];
				info.Description = strArray4[i];
				info.DefaultValue = strArray5[i];
				info.OrderId = i + 1;
				info.EnableNull = true;
				info.EnableShowOnSearchForm = true;
				switch (i)
				{
					case 0://所属栏目
						info.Disabled = false;
						info.EnableShowOnSearchForm = false;
						break;
					case 1://所属其它栏目
					case 2://专题
					case 4://标题前缀
					case 5://标题颜色
					case 6://标题字形
					case 7://显示“评论”链接
					case 16://内容页模板
					case 17://图片
						info.Disabled = true;
						info.EnableShowOnSearchForm = false;
						break;
					default:
						info.Disabled = false;
						info.EnableShowOnSearchForm = true;
						break;
				}
				info.CopyToSettings(collection19[i]);
				fieldList.Add(info);
			}
			#endregion

			return fieldList.ToXml();
		}

		/// <summary>
		/// 添加商品默认字段
		/// </summary>
		/// <returns></returns>
		public string AddShopDefaultField()
		{
			IList<FieldInfo> fieldList = new List<FieldInfo>();
			return fieldList.ToXml();
		}

		/// <summary>
		/// 添加模型:从指定的模型模板中生成新模型
		/// </summary>
		/// <param name="modelInfo"></param>
		/// <param name="modelTemplateId">模型模板ID</param>
		/// <returns></returns>
		public bool Add(ModelsEntity modelInfo, int modelTemplateId)
		{
			return Add(modelInfo, modelTemplateId, (ModelType)modelInfo.ModelType);
		}
		/// <summary>
		/// 添加模型：从指定的模型模板中生成新模型。
		/// 1.如果modelTemplateId为0并且type为ModelType.Content则先添加默认字段
		///   否则直接从指定模型导入字段 (字段以字符串形式存储)
		/// 2.如果检查模型字段信息中有自定义字段FieldLevel != 0,则创建表字段
		/// 3.清除模型缓存
		/// </summary>
		/// <param name="modelInfo"></param>
		/// <param name="modelTemplateId">模型模板ID</param>
		/// <param name="type">模型类型</param>
		/// <returns></returns>
		public bool Add(ModelsEntity modelInfo, int modelTemplateId, ModelType type)
		{
			bool flag = false;
			if (modelTemplateId > 0)
			{
				modelInfo.Field = _modelTemplatesRepository.Get(modelTemplateId)?.Field;
			}
			if (string.IsNullOrEmpty(modelInfo.Field))
			{
				switch (type)
				{
					case ModelType.Content:
						modelInfo.Field = AddDefaultField();
						break;
					case ModelType.Shop:
						modelInfo.Field = AddShopDefaultField();
						break;
				}
			}
			if (Add(modelInfo))
			{
				flag = true;
				if (modelTemplateId != 0)
				{
					List<FieldInfo> list = modelInfo.Field.ToXmlObject<List<FieldInfo>>();
					if (list != null)
					{
						list.Sort(new FieldInfoComparer());
						foreach (FieldInfo info in list)
						{
							if (info.FieldLevel != 0)
							{
								m_repository.AddFieldToTable(info, modelInfo.TableName);
							}
						}
					}
				}
				//是子母表模型
				if (modelInfo.IsParentChild)
				{
					AddParentChild(modelInfo);
				}
				RemoveCache();
			}
			return flag;
		}
		/// <summary>
		/// 为子母表模型添加子表模型
		/// </summary>
		/// <param name="parentInfo"></param>
		public void AddParentChild(ModelsEntity parentInfo)
		{
			ModelsEntity subInfo = new ModelsEntity();
			subInfo.ModelName = parentInfo.ModelName + "（明细）";
			subInfo.Description = parentInfo.Description;
			subInfo.ItemName = parentInfo.ItemName + "（明细）";
			subInfo.ItemUnit = parentInfo.ItemUnit;
			subInfo.ItemIcon = parentInfo.ItemIcon;
			subInfo.TableName = parentInfo.TableName + "_Item";
			subInfo.ModelType = parentInfo.ModelType;
			subInfo.IsCountHits = parentInfo.IsCountHits;
			subInfo.IsDisabled = true;
			subInfo.DefaultTemplateFile = "";
			subInfo.PrintTemplate = "";
			subInfo.SearchTemplate = "";
			subInfo.AdvanceSearchFormTemplate = "";
			subInfo.AdvanceSearchTemplate = "";
			subInfo.CommentManageTemplate = "";
			subInfo.AnonymouseTemplate = "";
			subInfo.UserAddContentTemplate = "";
			subInfo.AddInfoFilePath = parentInfo.AddInfoFilePath;
			subInfo.ManageInfoFilePath = parentInfo.ManageInfoFilePath;
			subInfo.PreviewInfoFilePath = parentInfo.PreviewInfoFilePath;
			subInfo.BatchInfoFilePath = parentInfo.BatchInfoFilePath;
			subInfo.IsEnableCharge = false;
			subInfo.IsEnableSignin = false;
			subInfo.IsEnableVote = false;
			subInfo.ChargeTips = "";
			subInfo.NeedPointChargeTips = "";
			subInfo.OutTimeChargeTips = "";
			subInfo.UsePointChargeTips = "";
			subInfo.MaxPerUser = 0;
			subInfo.IsVerificationCode = false;
			subInfo.IsParentChild = false;
			string strXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
				"<ArrayOfFieldInfo>" +
					"<FieldInfo Disabled=\"false\" Id=\"pid\" OrderId=\"1\">" +
						"<DefaultValue>0</DefaultValue>" +
						"<Description />" +
						"<EnableNull>false</EnableNull>" +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>" +
						"<FieldAlias>父ID</FieldAlias>" +
						"<FieldLevel>1</FieldLevel>" +
						"<FieldName>PID</FieldName>" +
						"<FieldType>IntegerType</FieldType>" +
						"<Settings>" +
							"<string>0</string>" +
							"<string />" +
							"<string>False</string>" +
						"</Settings>" +
						"<Tips />" +
					"</FieldInfo>" +
					"<FieldInfo Disabled=\"false\" Id=\"sortorder\" OrderId=\"2\">" +
						"<DefaultValue>0</DefaultValue>" +
						"<Description />" +
						"<EnableNull>false</EnableNull>" +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>" +
						"<FieldAlias>排序</FieldAlias>" +
						"<FieldLevel>1</FieldLevel>" +
						"<FieldName>SortOrder</FieldName>" +
						"<FieldType>IntegerType</FieldType>" +
						"<Settings>" +
							"<string>0</string>" +
							"<string />" +
							"<string>False</string>" +
						"</Settings>" +
						"<Tips />" +
					"</FieldInfo>" +
				"</ArrayOfFieldInfo>";
			subInfo.Field = strXML;
			if (Add(subInfo))
			{
				List<FieldInfo> list = subInfo.Field.ToXmlObject<List<FieldInfo>>();
				if (list != null)
				{
					list.Sort(new FieldInfoComparer());
					foreach (FieldInfo info in list)
					{
						if (info.FieldLevel != 0)
						{
							m_repository.AddFieldToTable(info, subInfo.TableName);
						}
					}
				}
			}
		}
		#endregion

		#region 修改
		/// <summary>
		/// 更新模型，删除缓存
		/// </summary>
		/// <param name="modelInfo"></param>
		/// <returns></returns>
		public override bool Update(ModelsEntity modelInfo)
		{
			if (base.Update(modelInfo))
			{
				RemoveCache();
				return true;
			}
			return false;
		}
		/// <summary>
		/// 更新字段到模型表(Models)
		/// </summary>
		/// <param name="modelType"></param>
		/// <param name="fieldList"></param>
		/// <returns></returns>
		public bool UpdateField(ModelType modelType, string fieldList)
		{
			try
			{
				m_repository.UpdateField(modelType, fieldList);
				RemoveCache();
				return true;
			}
			catch (DataException exception)
			{
				LogEntity logEntity = new LogEntity();
				logEntity.Category = (int)LogCategory.SystemAction;
				logEntity.Message = exception.Message;
				logEntity.ScriptName = "ModelsServiceAppDapper.cs";
				logEntity.Source = exception.Source;
				logEntity.Timestamp = DateTime.Now;
				logEntity.Title = "模型类型为" + modelType + "的fieldlist字段更新出错";
				logEntity.UserName = "System";
				_LogRepository.Add(logEntity);
				return false;
			}
		}
		/// <summary>
		/// 更新字段到模型表(Models)
		/// </summary>
		/// <param name="modelId"></param>
		/// <param name="fieldList"></param>
		/// <returns></returns>
		public bool UpdateField(int modelId, string fieldList)
		{
			try
			{
				m_repository.UpdateField(modelId, fieldList);
				RemoveCache();
				return true;
			}
			catch (DataException exception)
			{
				LogEntity logEntity = new LogEntity();
				logEntity.Category = (int)LogCategory.SystemAction;
				logEntity.Message = exception.Message;
				logEntity.ScriptName = "ModelsServiceAppDapper.cs";
				logEntity.Source = exception.Source;
				logEntity.Timestamp = DateTime.Now;
				logEntity.Title = "模型ID为" + modelId + "的fieldlist字段更新出错";
				logEntity.UserName = "System";
				_LogRepository.Add(logEntity);
				return false;
			}
		}
		#endregion

		#region 删除
		/// <summary>
		/// 删除模型同时删除相关信息。
		/// 1.检查模型中是否包含有信息数据，如果存在则记录日志，并返回数字1。
		/// 2.如果是商城模型且该模型存在订单，则不允许删除并记录日志，然后返回数字2。
		/// 3.删除模型对应扩展表。
		/// 4.删除关联表数据(NodesModelTemplate，Model，CommonInfo，CommonProduct，ProductData，ProductPrice，Cards,Work、WorkCategorySetting)。
		/// 5.删除模型的模板和标签文件。
		/// 6.清除缓存。
		/// 7.返回值含义：（0：删除成功；1：删除的模型中包含有数据；2：删除模型中存在订单；3：删除模型错误）
		/// </summary>
		/// <param name="modelId"></param>
		public int DeleteFull(int modelId)
		{
			var modelInfoById = Get(modelId);
			if(modelInfoById == null)
				return 0;
			if (_commonInfoRepository.IsExist(p => p.ModelID == modelId))
			{
				_LogRepository.SaveLog("删除的模型中包含有数据！", "删除的模型中包含有数据！", MyHttpContext.CurrentUserName,
					LogCategory.AdminErr, LogPriority.Low,
					"删除模型ID为" + modelId + "的模型中因为已经包含了数据而出错。如果要删除该模型请首先去删除该模型下的数据！", true);
				return 1;
			}
			if (modelInfoById.ModelType == (int)ModelType.Shop)
			{
				if (_orderItemRepository.IsExist(p=>p.TableName==modelInfoById.TableName))
				{
					_LogRepository.SaveLog("删除的模型中包含有订单数据！", "删除的模型中包含有订单数据！", MyHttpContext.CurrentUserName,
					   LogCategory.AdminErr, LogPriority.Low,
					   "删除模型ID为" + modelId + "的模型中因为已经包含了订单数据而出错。如果要删除该模型请首先去删除该模型下的数据！", true);
					return 2;
				}
			}
			try
			{
				using (var uow = _uowFactory.Create())
				{
					int result = 3;
					if (m_repository.DeleteTable(modelId))
					{
						_nodesModelTemplateRepository.Delete(p => p.ModelID == modelId);
						DeleteCustomFormDataByModelID(modelId);
						DeleteWorkCategoryCustomForm(modelId);
						DeleteTemplateAndLabel(modelId);
						if (Delete(modelId))
						{
							DeleteContentByModeID(modelId);
							if (modelInfoById.ModelType == (int)ModelType.Shop)
							{
								ExeSQL("Product_DeleteModel", new { TableName = modelInfoById.TableName }, CommandType.StoredProcedure);
							}
						}
						if (uow.Commit())
						{
							RemoveCache();
							result = 0;
						}
					}
					return result;
				}
			}
			catch (Exception exception)
			{
				_LogRepository.SaveLog("删除模型错误！", exception.Message, (string.IsNullOrEmpty(MyHttpContext.CurrentUserName))?"System": MyHttpContext.CurrentUserName,
					LogCategory.Exception, LogPriority.High,exception.Source, true);
				return 3;
			}
		}
		/// <summary>
		/// 按模型ID删除相应的内容信息(表：CommonInfo)
		/// </summary>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool DeleteContentByModeID(int modelId)
		{
			return _commonInfoRepository.Delete(p => p.ModelID == modelId);
		}
		/// <summary>
		/// 按模型ID删除自定义表单数据(表：Work)
		/// </summary>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool DeleteCustomFormDataByModelID(int modelId)
		{
			return _workRepository.Delete(p => p.FormID == modelId);
		}
		/// <summary>
		/// 删除自定义表单处理页信息(表：WorkCategorySetting)
		/// </summary>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool DeleteWorkCategoryCustomForm(int modelId)
		{
			return _workCategorySettingRepository.Delete(p => p.CustomFormID == modelId);
		}
		/// <summary>
		/// 删除指定模型的模板和标签文件
		/// </summary>
		/// <param name="modelId"></param>
		private void DeleteTemplateAndLabel(int modelId)
		{
			if (modelId >= 23)
			{
				var modelInfoById = GetCacheModelById(modelId);
				if (modelInfoById != null)
				{
					string virtualPath = FileHelper.ContentRootPath;
					string path = Utility.AppendTrailingSlash(virtualPath) + Utility.AppendTrailingSlash(ConfigHelper.Get<SiteOptionConfig>().TemplateDir) + modelInfoById.ModelName;
					if (Directory.Exists(path))
					{
						Directory.Delete(path, true);
					}
					string commonTemplatePath = Utility.AppendTrailingSlash(virtualPath) + "CommonTemplate/";
					if (!Directory.Exists(commonTemplatePath))
					{
						Directory.CreateDirectory(commonTemplatePath);
					}
					FileInfo[] files = new DirectoryInfo(commonTemplatePath).GetFiles();
					string LabelDir = Utility.AppendTrailingSlash(virtualPath + ConfigHelper.Get<SiteOptionConfig>().LabelDir);
					foreach (FileInfo info in files)
					{
						if (string.Compare(info.Extension, ".config", StringComparison.OrdinalIgnoreCase) == 0)
						{
							string modelFileName = info.Name.ToLower().Replace(".config", "_" + modelInfoById.ModelName + ".config");
							if (File.Exists(LabelDir + modelFileName))
							{
								File.Delete(LabelDir + modelFileName);
							}
						}
					}
				}
			}
		}
		#endregion

		#region 启用模型、启用收费、启用签收
		/// <summary>
		/// 启用/禁用模型
		/// </summary>
		/// <param name="id">模型ID</param>
		/// <param name="disabled">是否禁用</param>
		/// <returns></returns>
		public bool Disable(int id, bool disabled)
		{
			bool flag = Update("IsDisabled=@IsDisabled", " and ModelID=@ModelID", new { IsDisabled = disabled, ModelID = id });
			if (flag)
				RemoveCache();
			return flag;
		}
		/// <summary>
		/// 设置模型启用收费设置
		/// </summary>
		/// <param name="id">模型ID</param>
		/// <param name="charge">是否启用收费</param>
		/// <returns></returns>
		public bool EnableCharge(int id, bool charge)
		{
			bool flag = Update("IsEnableCharge = @IsEnableCharge", " and ModelID=@ModelID", new { IsEnableCharge = charge, ModelID = id });
			if (flag)
				RemoveCache();
			return flag;
		}
		/// <summary>
		/// 设置模型启用签收功能
		/// </summary>
		/// <param name="id">模型ID</param>
		/// <param name="signIn">是否启用签收</param>
		/// <returns></returns>
		public bool EnableSignIn(int id, bool signIn)
		{
			bool flag = Update("IsEnableSignin = @IsEnableSignin", " and ModelID=@ModelID", new { IsEnableSignin = signIn, ModelID = id });
			if (flag)
				RemoveCache();
			return flag;
		}
		#endregion

		#region 字段管理

		#region 得到字段列表(xml字符串)
		/// <summary>
		/// 得到字段列表(xml字符串)
		/// </summary>
		/// <param name="modelId"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public string GetXmlFieldByModelId(int modelId, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return GetScalar(scalar: p => p.Field, predicate: p => p.ModelID == modelId, writeAndRead: writeAndRead);
		}
		/// <summary>
		/// 得到字段列表(xml字符串)
		/// </summary>
		/// <param name="modelId"></param>
		/// <param name="disable">是否禁用</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public string GetXmlFieldByModelId(int modelId, bool disable, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			string xmlFieldList = GetXmlFieldByModelId(modelId,writeAndRead);
			if (string.IsNullOrWhiteSpace(xmlFieldList))
				return string.Empty;
			List<FieldInfo> result = new List<FieldInfo>();
			var list = xmlFieldList.ToXmlObject<List<FieldInfo>>();
			if (list != null && list.Count > 0)
			{
				foreach (var item in list)
				{
					if (item.Disabled == disable)
					{
						result.Add(item);
					}
				}
				result.Sort(new FieldInfoComparer());
			}
			return result.ToXml();
		}
		/// <summary>
		/// 得到字段列表(xml字符串)
		/// </summary>
		/// <param name="modelType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public string GetXmlFieldByModelType(ModelType modelType, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			Expression<Func<ModelsEntity, bool>> funcWhere = w => true;
			if (modelType != ModelType.None)
			{
				var enumValue = (int)modelType;
				funcWhere = funcWhere.And(p => p.ModelType == enumValue);
			}
			return GetScalar(scalar: p => p.Field, predicate: funcWhere, writeAndRead: writeAndRead);
		}
		/// <summary>
		/// 得到字段列表(xml字符串)
		/// </summary>
		/// <param name="modelType"></param>
		/// <param name="disable">是否禁用</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public string GetXmlFieldByModelType(ModelType modelType, bool disable, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			string xmlFieldList = GetXmlFieldByModelType(modelType, writeAndRead);
			if (string.IsNullOrWhiteSpace(xmlFieldList))
				return string.Empty;
			List<FieldInfo> result = new List<FieldInfo>();
			var list = xmlFieldList.ToXmlObject<List<FieldInfo>>();
			if (list != null && list.Count > 0)
			{
				foreach (var item in list)
				{
					if (item.Disabled == disable)
					{
						result.Add(item);
					}
				}
				result.Sort(new FieldInfoComparer());
			}
			return result.ToXml();
		}
		/// <summary>
		/// 得到商品模型的常用公共属性字段的XML片段
		/// </summary>
		/// <returns></returns>
		public string GetCommonShopXmlFieldList()
		{
			string shopField = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
				"<ArrayOfFieldInfo>    " +
					"<FieldInfo Disabled=\"false\" Id=\"productname\" OrderId=\"1\">      " +
						"<DefaultValue />      <Description />      " +
						"<EnableNull>true</EnableNull>      " +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>      " +
						"<FieldAlias>商品名称</FieldAlias>      " +
						"<FieldLevel>1</FieldLevel>      " +
						"<FieldName>ProductName</FieldName>      " +
						"<FieldType>TextType</FieldType>      " +
						"<Settings>        " +
							"<string>200</string>        " +
							"<string>30</string>        " +
							"<string>False</string>        " +
							"<string>0</string>        " +
							"<string>False</string>        " +
							"<string>False</string>        " +
							"<string>False</string>      " +
						"</Settings>      " +
						"<Tips />    " +
					"</FieldInfo>    " +
					"<FieldInfo Disabled=\"false\" Id=\"productnum\" OrderId=\"2\">      " +
						"<DefaultValue />      <Description />      " +
						"<EnableNull>false</EnableNull>      " +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>      " +
						"<FieldAlias>商品编号</FieldAlias>      " +
						"<FieldLevel>1</FieldLevel>      " +
						"<FieldName>ProductNum</FieldName>      " +
						"<FieldType>TextType</FieldType>      " +
						"<Settings>        " +
							"<string>200</string>        " +
							"<string>30</string>        " +
							"<string>False</string>        " +
							"<string>0</string>        " +
							"<string>False</string>        " +
							"<string>False</string>        " +
							"<string>False</string>      " +
						"</Settings>      " +
						"<Tips />    " +
					"</FieldInfo>    " +
					"<FieldInfo Disabled=\"false\" Id=\"unit\" OrderId=\"3\">      " +
						"<DefaultValue>个</DefaultValue>      <Description />      " +
						"<EnableNull>false</EnableNull>      " +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>      " +
						"<FieldAlias>商品单位</FieldAlias>      " +
						"<FieldLevel>1</FieldLevel>      " +
						"<FieldName>Unit</FieldName>      " +
						"<FieldType>TextType</FieldType>      " +
						"<Settings>        " +
							"<string>200</string>        " +
							"<string>30</string>        " +
							"<string>False</string>        " +
							"<string>0</string>        " +
							"<string>False</string>        " +
							"<string>False</string>        " +
							"<string>False</string>      " +
						"</Settings>      " +
						"<Tips />    " +
					"</FieldInfo>    " +
					"<FieldInfo Disabled=\"false\" Id=\"productintro\" OrderId=\"4\">      " +
						"<DefaultValue />      <Description />      " +
						"<EnableNull>false</EnableNull>      " +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>      " +
						"<FieldAlias>商品简介</FieldAlias>      " +
						"<FieldLevel>1</FieldLevel>      " +
						"<FieldName>ProductIntro</FieldName>      " +
						"<FieldType>MultipleTextType</FieldType>      " +
						"<Settings>        " +
							"<string>500</string>        " +
							"<string>80</string>        " +
							"<string>False</string>        " +
							"<string>False</string>        " +
							"<string>False</string>      " +
						"</Settings>      " +
						"<Tips />    " +
					"</FieldInfo>    " +
					"<FieldInfo Disabled=\"false\" Id=\"productexplain\" OrderId=\"5\">      " +
						"<DefaultValue />      <Description />      " +
						"<EnableNull>false</EnableNull>      " +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>      " +
						"<FieldAlias>详细介绍</FieldAlias>      " +
						"<FieldLevel>1</FieldLevel>      " +
						"<FieldName>ProductExplain</FieldName>      " +
						"<FieldType>ContentType</FieldType>      " +
						"<Settings>        " +
							"<string>600</string>        " +
							"<string>500</string>        " +
							"<string>jpg|gif|jpeg|png|bmp</string>        " +
							"<string>swf|fla|rm|rmvb|mp3|mpeg|avi|mpeg2|wmv|midi</string>        " +
							"<string>txt|doc|rar|zip|xls</string>        " +
							"<string>False</string>        " +
							"<string>False</string>        " +
							"<string>10240</string>        " +
							"<string>{$Year}{$Month}{$Day}{$Hour}{$Minute}{$Second}</string>      " +
						"</Settings>      " +
						"<Tips />    " +
					"</FieldInfo>    " +
					"<FieldInfo Disabled=\"false\" Id=\"productpic\" OrderId=\"6\">      " +
						"<DefaultValue />      <Description />      " +
						"<EnableNull>false</EnableNull>      " +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>      " +
						"<FieldAlias>商品清晰图</FieldAlias>      " +
						"<FieldLevel>1</FieldLevel>      " +
						"<FieldName>ProductPic</FieldName>      " +
						"<FieldType>PictureType</FieldType>      " +
						"<Settings>        " +
							"<string>30</string>        " +
							"<string>10240</string>        " +
							"<string>jpg|gif|jpeg|png|bmp</string>        " +
							"<string>False</string>        " +
							"<string>False</string>        " +
							"<string>False</string>        " +
							"<string>True</string>        " +
							"<string>False</string>        " +
							"<string>{$Year}{$Month}{$Day}{$Hour}{$Minute}{$Second}</string>      " +
						"</Settings>      " +
						"<Tips />    " +
					"</FieldInfo>    " +
					"<FieldInfo Disabled=\"false\" Id=\"multiplephoto\" OrderId=\"7\">      " +
						"<DefaultValue />      <Description />      " +
						"<EnableNull>false</EnableNull>      " +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>      " +
						"<FieldAlias>商品多图</FieldAlias>      " +
						"<FieldLevel>1</FieldLevel>      " +
						"<FieldName>MultiplePhoto</FieldName>      " +
						"<FieldType>MultiplePhotoType</FieldType>      " +
						"<Settings>        " +
							"<string>10240</string>        " +
							"<string>jpg|gif|jpeg|png|bmp</string>        " +
							"<string>False</string>        " +
							"<string>{$Year}{$Month}{$Day}{$Hour}{$Minute}{$Second}</string>      " +
						"</Settings>      " +
						"<Tips />    " +
					"</FieldInfo>    " +
					"<FieldInfo Disabled=\"false\" Id=\"trademarkname\" OrderId=\"8\">      " +
						"<DefaultValue />      <Description />      " +
						"<EnableNull>false</EnableNull>      " +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>      " +
						"<FieldAlias>商品品牌</FieldAlias>      " +
						"<FieldLevel>1</FieldLevel>      " +
						"<FieldName>TrademarkName</FieldName>      " +
						"<FieldType>TextType</FieldType>      " +
						"<Settings>        " +
							"<string>200</string>        " +
							"<string>30</string>        " +
							"<string>False</string>        " +
							"<string>0</string>        " +
							"<string>False</string>        " +
							"<string>False</string>        " +
							"<string>False</string>      " +
						"</Settings>      " +
						"<Tips />    " +
					"</FieldInfo>    " +
					"<FieldInfo Disabled=\"false\" Id=\"price_market\" OrderId=\"9\">      " +
						"<DefaultValue />      <Description />      " +
						"<EnableNull>false</EnableNull>      " +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>      " +
						"<FieldAlias>市场价</FieldAlias>      " +
						"<FieldLevel>1</FieldLevel>      " +
						"<FieldName>Price_Market</FieldName>      " +
						"<FieldType>MoneyType</FieldType>      " +
						"<Settings>        <string />        <string />      </Settings>      " +
						"<Tips />    " +
					"</FieldInfo>    " +
					"<FieldInfo Disabled=\"false\" Id=\"price\" OrderId=\"10\">      " +
						"<DefaultValue />      <Description />      " +
						"<EnableNull>false</EnableNull>      " +
						"<EnableShowOnSearchForm>false</EnableShowOnSearchForm>      " +
						"<FieldAlias>零售价</FieldAlias>      " +
						"<FieldLevel>1</FieldLevel>      " +
						"<FieldName>Price</FieldName>      " +
						"<FieldType>MoneyType</FieldType>      " +
						"<Settings>        <string />        <string />      </Settings>      " +
						"<Tips />    " +
					"</FieldInfo>  " +
				"</ArrayOfFieldInfo>";
			return shopField;
		}
		#endregion

		#region 得到字段信息实体类列表
		/// <summary>
		/// 按节点ID获取绑定的第一个模型的字段列表
		/// </summary>
		/// <param name="nodeId"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<FieldInfo> GetFieldListByNodeId(int nodeId, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var modelIDByNodeID = _nodesModelTemplateRepository.GetScalar(predicate: p => p.NodeID == nodeId, scalar: p => p.ModelID, writeAndRead: writeAndRead);
			return GetFieldListByModelId((int)modelIDByNodeID, writeAndRead);
		}
		/// <summary>
		/// 获取指定模型ID的字段列表
		/// </summary>
		/// <param name="modelId"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<FieldInfo> GetFieldListByModelId(int modelId, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			List<FieldInfo> result = new List<FieldInfo>();
			string xmlFieldByModelId = GetXmlFieldByModelId(modelId, writeAndRead);
			var list = xmlFieldByModelId.ToXmlObject<List<FieldInfo>>();
			if (list != null && list.Count > 0)
			{
				list.Sort(new FieldInfoComparer());
				result = list;
			}
			return result;
		}
		/// <summary>
		/// 获取指定模型ID的字段列表
		/// </summary>
		/// <param name="modelId"></param>
		/// <param name="disable">字段是否禁用</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<FieldInfo> GetFieldListByModelId(int modelId, bool disable, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			List<FieldInfo> result = new List<FieldInfo>();
			string xmlFieldByModelId = GetXmlFieldByModelId(modelId, writeAndRead);
			var list = xmlFieldByModelId.ToXmlObject<List<FieldInfo>>();
			if (list != null && list.Count > 0)
			{
				foreach (var item in list)
				{
					if(item.Disabled == disable)
					{
						result.Add(item);
					}
				}
				result.Sort(new FieldInfoComparer());
			}
			return result;
		}
		/// <summary>
		/// 获取指定模型类型的字段列表
		/// </summary>
		/// <param name="modelType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<FieldInfo> GetFieldListByModelType(ModelType modelType, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			List<FieldInfo> result = new List<FieldInfo>();
			string xmlFieldByModelId = GetXmlFieldByModelType(modelType, writeAndRead);
			var list = xmlFieldByModelId.ToXmlObject<List<FieldInfo>>();
			if (list != null && list.Count > 0)
			{
				list.Sort(new FieldInfoComparer());
				result = list;
			}
			return result;
		}
		/// <summary>
		/// 获取指定模型类型的字段列表
		/// </summary>
		/// <param name="modelType"></param>
		/// <param name="disable">字段是否禁用</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<FieldInfo> GetFieldListByModelType(ModelType modelType, bool disable, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			List<FieldInfo> result = new List<FieldInfo>();
			string xmlFieldByModelId = GetXmlFieldByModelType(modelType, writeAndRead);
			var list = xmlFieldByModelId.ToXmlObject<List<FieldInfo>>();
			if (list != null && list.Count > 0)
			{
				foreach (var item in list)
				{
					if (item.Disabled == disable)
					{
						result.Add(item);
					}
				}
				result.Sort(new FieldInfoComparer());
			}
			return result;
		}
		/// <summary>
		/// 得到商品模型的常用公共属性字段列表
		/// </summary>
		/// <returns></returns>
		public IList<FieldInfo> GetCommonShopFieldList()
		{
			List<FieldInfo> list = GetCommonShopXmlFieldList().ToXmlObject<List<FieldInfo>>();
			if (list != null)
			{
				list.Sort(new FieldInfoComparer());
			}
			return list;
		}
		/// <summary>
		/// 获取模型字段中可用于搜索的所有字段列表
		/// </summary>
		/// <param name="modelType"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<FieldInfo> GetSearchFieldList(ModelType modelType, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			IList<FieldInfo> fieldListByModelType = GetFieldListByModelType(modelType, writeAndRead);
			List<FieldInfo> list2 = new List<FieldInfo>();
			if ((fieldListByModelType != null) && (fieldListByModelType.Count > 0))
			{
				foreach (FieldInfo info in fieldListByModelType)
				{
					if (info.EnableShowOnSearchForm)
					{
						list2.Add(info);
					}
				}
			}
			return list2;
		}
		/// <summary>
		/// 从xml字段信息中获取字段列表
		/// </summary>
		/// <param name="xmlField">字段的XML信息</param>
		/// <returns></returns>
		public IList<FieldInfo> GetFieldListByXmlField(string xmlField)
		{
			var list = xmlField.ToXmlObject<List<FieldInfo>>();
			if (list != null)
			{
				list.Sort(new FieldInfoComparer());
			}
			return list;
		}
		/// <summary>
		/// 获取字段信息列表：词典形式(FieldName , FieldInfo)
		/// </summary>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public Dictionary<string, FieldInfo> GetFieldDictList(int modelId)
		{
			var fieldList = GetFieldListByModelId(modelId,false);
			Dictionary<string, FieldInfo> dictionary = new Dictionary<string, FieldInfo>();
			foreach (FieldInfo info in fieldList)
			{
				dictionary.Add(info.FieldName, info);
			}
			return dictionary;
		}
		#endregion

		#region 得到字段信息对象
		/// <summary>
		/// 获取模型字段信息
		/// </summary>
		/// <param name="modeType"></param>
		/// <param name="fieldName"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public FieldInfo GetFieldInfoByFieldName(ModelType modeType, string fieldName, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var xmlFieldList = GetXmlFieldByModelType(modeType, writeAndRead);
			if (string.IsNullOrEmpty(xmlFieldList))
				return null;
			string xmlField = XmlHelper.Instance(xmlFieldList, XmlType.Content).SelectNode("/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]");
			return xmlField.ToXmlObject<FieldInfo>();
		}
		/// <summary>
		/// 获取模型字段信息
		/// </summary>
		/// <param name="modelId"></param>
		/// <param name="fieldName"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public FieldInfo GetFieldInfoByFieldName(int modelId, string fieldName, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			var xmlFieldList = GetXmlFieldByModelId(modelId, writeAndRead);
			if (string.IsNullOrEmpty(xmlFieldList))
				return null;
			string xmlField = XmlHelper.Instance(xmlFieldList, XmlType.Content).SelectNode("/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]");
			return xmlField.ToXmlObject<FieldInfo>();
		}
		/// <summary>
		/// 获取商品模型公共属性字段信息
		/// </summary>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		public FieldInfo GetShopFieldInfoByFieldName(string fieldName)
		{
			string xmlField = XmlHelper.Instance(GetCommonShopXmlFieldList(), XmlType.Content).SelectNode("/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]");
			return xmlField.ToXmlObject<FieldInfo>();
		}
		#endregion

		#region 禁用字段、字段是否必填、字段允许搜索、字段排序
		/// <summary>
		///  禁用模型字段
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="disabled"></param>
		/// <param name="modelType"></param>
		/// <returns></returns>
		public bool SetFieldDisabled(string fieldName, bool disabled, ModelType modelType)
		{
			return UpdateField(modelType, SetFieldDisabled(fieldName, disabled, GetXmlFieldByModelType(modelType)));
		}
		/// <summary>
		/// 禁用模型字段
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="disabled"></param>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool SetFieldDisabled(string fieldName, bool disabled, int modelId)
		{
			return UpdateField(modelId, SetFieldDisabled(fieldName, disabled, GetXmlFieldByModelId(modelId)));
		}
		private string SetFieldDisabled(string fieldName, bool disabled, string xmlFieldList)
		{
			var manage = XmlHelper.Instance(xmlFieldList, XmlType.Content);
			string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]";
			manage.SetAttributesValue(nodeName, "Disabled", disabled.ToString().ToLower());
			return manage.Xml;
		}

		/// <summary>
		///  模型字段必填
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="enable">true:必填；false:可空；</param>
		/// <param name="modelType"></param>
		/// <returns></returns>
		public bool SetFieldEnableNull(string fieldName, bool enable, ModelType modelType)
		{
			return UpdateField(modelType, SetFieldEnableNull(fieldName, enable, GetXmlFieldByModelType(modelType)));
		}
		/// <summary>
		///  模型字段必填
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="enable">true:必填；false:可空；</param>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool SetFieldEnableNull(string fieldName, bool enable, int modelId)
		{
			return UpdateField(modelId, SetFieldEnableNull(fieldName, enable, GetXmlFieldByModelId(modelId)));
		}
		private string SetFieldEnableNull(string fieldName, bool enable, string xmlFieldList)
		{
			var manage = XmlHelper.Instance(xmlFieldList, XmlType.Content);
			string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]/EnableNull";
			manage.SetNodeValue(nodeName, enable.ToString().ToLower());
			return manage.Xml;
		}

		/// <summary>
		///  模型字段允许搜索
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="enable">true:允许；false:不允许；</param>
		/// <param name="modelType"></param>
		/// <returns></returns>
		public bool SetFieldEnableSearch(string fieldName, bool enable, ModelType modelType)
		{
			return UpdateField(modelType, SetFieldEnableSearch(fieldName, enable, GetXmlFieldByModelType(modelType)));
		}
		/// <summary>
		///  模型字段允许搜索
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="enable">true:允许；false:不允许；</param>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool SetFieldEnableSearch(string fieldName, bool enable, int modelId)
		{
			return UpdateField(modelId, SetFieldEnableSearch(fieldName, enable, GetXmlFieldByModelId(modelId)));
		}
		private string SetFieldEnableSearch(string fieldName, bool enable, string xmlFieldList)
		{
			var manage = XmlHelper.Instance(xmlFieldList, XmlType.Content);
			string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]/EnableShowOnSearchForm";
			manage.SetNodeValue(nodeName, enable.ToString().ToLower());
			return manage.Xml;
		}

		/// <summary>
		/// 重设模型字段顺序
		/// </summary>
		/// <param name="fieldInfoList"></param>
		/// <param name="modelType"></param>
		/// <returns></returns>
		public bool SetOrderId(IList<FieldInfo> fieldInfoList, ModelType modelType)
		{
			var manage = XmlHelper.Instance(GetXmlFieldByModelType(modelType), XmlType.Content);
			foreach (FieldInfo info in fieldInfoList)
			{
				string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + info.Id.ToLower() + "\"]";
				manage.SetAttributesValue(nodeName, "OrderId", info.OrderId.ToString());
			}
			return UpdateField(modelType, manage.Xml);
		}
		/// <summary>
		/// 重设模型字段顺序
		/// </summary>
		/// <param name="fieldInfoList"></param>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool SetOrderId(IList<FieldInfo> fieldInfoList, int modelId)
		{
			var manage = XmlHelper.Instance(GetXmlFieldByModelId(modelId), XmlType.Content);
			foreach (FieldInfo info in fieldInfoList)
			{
				string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + info.Id.ToLower() + "\"]";
				manage.SetAttributesValue(nodeName, "OrderId", info.OrderId.ToString());
			}
			return UpdateField(modelId, manage.Xml);
		}
		/// <summary>
		/// 更新模型字段的顺序
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="modelId"></param>
		/// <param name="orderId">排序号</param>
		/// <returns></returns>
		public bool SetOrderId(string fieldName, int modelId, int orderId)
		{
			var manage = XmlHelper.Instance(GetXmlFieldByModelId(modelId), XmlType.Content);
			string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]";
			manage.SetAttributesValue(nodeName, "OrderId", orderId.ToString());
			return UpdateField(modelId, manage.Xml);
		}
		#endregion

		#region 字段是否存在
		/// <summary>
		/// 判断模型中字段是否存在
		/// </summary>
		/// <param name="modeType"></param>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		public bool FieldExists(ModelType modeType, string fieldName)
		{
			string xmlFieldList = GetXmlFieldByModelType(modeType);
			return FieldExists(xmlFieldList, fieldName);
		}
		/// <summary>
		/// 判断模型中字段是否存在
		/// </summary>
		/// <param name="modelId"></param>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		public bool FieldExists(int modelId, string fieldName)
		{
			string xmlFieldList = GetXmlFieldByModelId(modelId);
			return FieldExists(xmlFieldList, fieldName);
		}
		/// <summary>
		/// 判断模型中字段是否存在
		/// </summary>
		/// <param name="xmlFieldList">XML形式的字段列表</param>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		public bool FieldExists(string xmlFieldList, string fieldName)
		{
			if (string.IsNullOrEmpty(xmlFieldList))
			{
				return false;
			}
			string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id='" + fieldName.ToLower() + "']";
			return XmlHelper.Instance(xmlFieldList, XmlType.Content).ExistsNode(nodeName);
		}
		#endregion

		#region 字段类型、字段别名
		/// <summary>
		/// 获取字段类型名称：单行文本 行政区划 商品款式 商品属性 关键字 多图片
		/// </summary>
		/// <param name="fieldType"></param>
		/// <returns></returns>
		public string GetFieldTypeName(int fieldType)
		{
			return EnumHelper.GetDescription((FieldType)fieldType);
		}
		/// <summary>
		/// 获取字段类型对应的数据类型
		/// </summary>
		/// <param name="fieldtype"></param>
		/// <returns></returns>
		public Type GetFieldDataType(FieldType fieldtype)
		{
			switch (fieldtype)
			{
				case FieldType.TextType:
				case FieldType.MultipleTextType:
				case FieldType.MultipleHtmlTextType:
				case FieldType.ListBoxType:
				case FieldType.ListBoxIntroType:
				case FieldType.LookType:
				case FieldType.LinkType:
				case FieldType.CountType:
				case FieldType.PictureType:
				case FieldType.FileType:
				case FieldType.BigFileType:
				case FieldType.ColorType:
				case FieldType.TemplateType:
				case FieldType.AuthorType:
				case FieldType.SourceType:
				case FieldType.KeywordType:
				case FieldType.OperatingType:
				case FieldType.DownServerType:
				case FieldType.Producer:
				case FieldType.Trademark:
				case FieldType.ContentType:
				case FieldType.TitleType:
				case FieldType.MultiplePhotoType:
					return typeof(string);

				case FieldType.NumberType:
					return typeof(double);

				case FieldType.MoneyType:
					return typeof(decimal);

				case FieldType.DateTimeType:
					return typeof(DateTime);

				case FieldType.BoolType:
					return typeof(bool);

				case FieldType.NodeType:
				case FieldType.InfoType:
				case FieldType.StatusType:
				case FieldType.RegionType:
				case FieldType.IndustryCategory:
					return typeof(string);

				case FieldType.ListBoxDataType:
					return typeof(int);
			}
			return typeof(int);
		}

		/// <summary>
		/// 获取字段别名及字段名数据表（FieldAlias、FieldName）
		/// </summary>
		/// <param name="modelId"></param>
		/// <param name="fieldType">要查找的字段类型</param>
		/// <returns></returns>
		public DataTable GetFieldNames(int modelId, FieldType[] fieldType)
		{
			DataTable table = new DataTable();
			table.Columns.Add("FieldAlias");
			table.Columns.Add("FieldName");
			foreach (FieldInfo info in GetFieldListByModelId(modelId))
			{
				if ((info.FieldType == fieldType[0]) || (info.FieldType == fieldType[1]))
				{
					DataRow row = table.NewRow();
					row["FieldAlias"] = info.FieldAlias;
					row["FieldName"] = info.FieldName;
					table.Rows.Add(row);
				}
			}
			return table;
		}
		#endregion

		#region 添加
		/// <summary>
		/// 将模型字段信息更新到模型表中，并添加字段到模型的对应扩展表中。
		/// 1.从模型表中取出模型字段信息(xml字段字符串),如果未取到则记录log。
		/// 2.判断字段名是否已存在。
		/// 3.如果字段类型为上传文件，并且开启了保存文件大小选项，则添加新字段到字段列表中。
		/// 4.更新XML字段信息到模型表中。
		/// 5.如果fieldInfo.FieldType != FieldType.Property and (fieldInfo.FieldType != FieldType.ProductStyle)将字段添加到扩展表。
		/// 6.清除模型缓存。
		/// </summary>
		/// <param name="fieldInfo"></param>
		/// <param name="modelType"></param>
		/// <returns></returns>
		public ResultInfo AddFieldToTable(FieldInfo fieldInfo, ModelType modelType)
		{
			ResultInfo resultInfo = new ResultInfo();
			IList<FieldInfo> list = new List<FieldInfo>();
			string xmlFieldByModelType = GetXmlFieldByModelType(modelType);
			if (FieldExists(xmlFieldByModelType, fieldInfo.FieldName))
			{
				resultInfo.Status = 0;
				resultInfo.Msg = "字段已经存在！";
				return resultInfo;
			}
			if (fieldInfo.FieldType == FieldType.FileType && DataConverter.CBoolean(fieldInfo.Settings[3]) && !string.IsNullOrEmpty(fieldInfo.Settings[4]))
			{
				FieldInfo info = new FieldInfo();
				info.Id = fieldInfo.Settings[4];
				info.FieldName = fieldInfo.Settings[4];
				info.FieldType = FieldType.TextType;
				info.FieldLevel = 2;
				info.OrderId = 0;
				resultInfo = AddFieldToTable(info, modelType);
				if (resultInfo.Status == 0)
				{
					return resultInfo;
				}
				else
				{
					xmlFieldByModelType = GetXmlFieldByModelType(modelType);
				}
			}
			if (!string.IsNullOrEmpty(xmlFieldByModelType))
			{
				list = xmlFieldByModelType.ToXmlObject<List<FieldInfo>>();
			}
			else
			{
				LogEntity logEntity = new LogEntity();
				logEntity.Category = (int)LogCategory.SystemAction;
				logEntity.Message = "模型类型 为" + modelType + "的模型没有获取到字段";
				logEntity.ScriptName = "ModelsServiceAppDapper.cs";
				logEntity.Source = "GetXmlFieldByModelType(modelType)返回的内容为空";
				logEntity.Timestamp = DateTime.Now;
				logEntity.Title = "AddFieldToTable方法出错";
				logEntity.UserName = "System";
				_LogRepository.Add(logEntity);
			}
			list.Add(fieldInfo);
			xmlFieldByModelType = list.ToXml();
			bool flag = UpdateField(modelType, xmlFieldByModelType);
			if (flag && (fieldInfo.FieldType != FieldType.Property) && (fieldInfo.FieldType != FieldType.ProductStyle))
			{
				flag = AddTableField(fieldInfo, modelType);
			}
			RemoveCache();
			if (flag)
			{
				resultInfo.Status = 1;
				resultInfo.Msg = "添加字段成功！";
			}
			else
			{
				resultInfo.Status = 0;
				resultInfo.Msg = "添加字段失败！";
			}
			return resultInfo;
		}
		/// <summary>
		/// 将模型字段信息更新到模型表中，并添加字段到模型的对应扩展表中。
		/// 1.从模型表中取出模型字段信息(xml字段字符串),如果未取到则记录log。
		/// 2.判断字段名是否已存在。
		/// 3.如果字段类型为上传文件，并且开启了保存文件大小选项，则添加新字段到字段列表中。
		/// 4.更新XML字段信息到模型表中。
		/// 5.如果fieldInfo.FieldType != FieldType.Property and (fieldInfo.FieldType != FieldType.ProductStyle)将字段添加到扩展表。
		/// 6.清除模型缓存。
		/// </summary>
		/// <param name="fieldInfo"></param>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public ResultInfo AddFieldToTable(FieldInfo fieldInfo, int modelId)
		{
			ResultInfo resultInfo = new ResultInfo();
			IList<FieldInfo> list = new List<FieldInfo>();
			string xmlFieldByModelId = GetXmlFieldByModelId(modelId);
			if (FieldExists(xmlFieldByModelId, fieldInfo.FieldName))
			{
				resultInfo.Status = 0;
				resultInfo.Msg = "字段已经存在！";
				return resultInfo;
			}
			if (fieldInfo.FieldType == FieldType.FileType && DataConverter.CBoolean(fieldInfo.Settings[3]) && !string.IsNullOrEmpty(fieldInfo.Settings[4]))
			{
				FieldInfo info = new FieldInfo();
				info.Id = fieldInfo.Settings[4];
				info.FieldName = fieldInfo.Settings[4];
				info.FieldType = FieldType.TextType;
				info.FieldLevel = 2;
				info.OrderId = 0;
				resultInfo = AddFieldToTable(info, modelId);
				if (resultInfo.Status == 0)
				{
					return resultInfo;
				}
				else
				{
					xmlFieldByModelId = GetXmlFieldByModelId(modelId);
				}
			}
			if (!string.IsNullOrEmpty(xmlFieldByModelId))
			{
				list = xmlFieldByModelId.ToXmlObject<List<FieldInfo>>();
			}
			else
			{
				LogEntity logEntity = new LogEntity();
				logEntity.Category = (int)LogCategory.SystemAction;
				logEntity.Message = "模型ID 为" + modelId + "的模型没有获取到字段";
				logEntity.ScriptName = "ModelsServiceAppDapper.cs";
				logEntity.Source = "GetXmlFieldByModelId(modelId)返回的内容为空";
				logEntity.Timestamp = DateTime.Now;
				logEntity.Title = "AddFieldToTable方法出错";
				logEntity.UserName = "System";
				_LogRepository.Add(logEntity);
			}
			list.Add(fieldInfo);
			xmlFieldByModelId = list.ToXml();
			bool flag = UpdateField(modelId, xmlFieldByModelId);
			if (flag && (fieldInfo.FieldType != FieldType.Property) && (fieldInfo.FieldType != FieldType.ProductStyle))
			{
				flag = AddTableField(fieldInfo, modelId);
			}
			RemoveCache();
			if (flag)
			{
				resultInfo.Status = 1;
				resultInfo.Msg = "添加字段成功！";
			}
			else
			{
				resultInfo.Status = 0;
				resultInfo.Msg = "添加字段失败！";
			}
			return resultInfo;
		}

		/// <summary>
		/// 添加字段到模型扩展表中：如果添加出错则记录日志
		/// </summary>
		/// <param name="fieldInfo"></param>
		/// <param name="modelType"></param>
		/// <returns></returns>
		public bool AddTableField(FieldInfo fieldInfo, ModelType modelType)
		{
			var modelInfoByModelType = GetModelByModelType(modelType);
			try
			{
				m_repository.AddFieldToTable(fieldInfo, modelInfoByModelType.TableName);
				RemoveCache();
				return true;
			}
			catch (DataException exception)
			{
				LogEntity logEntity = new LogEntity();
				logEntity.Category = (int)LogCategory.SystemAction;
				logEntity.Message = string.Concat(new object[] { "模型类型为", modelType, "的模型在修改", modelInfoByModelType.TableName, "表的字段时产生错误！" });
				logEntity.ScriptName = "ModelsServiceAppDapper.cs";
				logEntity.Source = "m_repository.AddFieldToTable(fieldInfo, modelInfo.TableName)错误<br/>" + exception.Source;
				logEntity.Timestamp = DateTime.Now;
				logEntity.Title = "AddTableField方法出错";
				logEntity.UserName = "System";
				_LogRepository.Add(logEntity);
				return false;
			}
		}
		/// <summary>
		/// 添加字段到模型扩展表中：如果添加出错则记录日志
		/// </summary>
		/// <param name="fieldInfo"></param>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool AddTableField(FieldInfo fieldInfo, int modelId)
		{
			var modelInfoById = GetCacheModelById(modelId);
			try
			{
				m_repository.AddFieldToTable(fieldInfo, modelInfoById.TableName);
				RemoveCache();
				return true;
			}
			catch (DataException exception)
			{
				LogEntity logEntity = new LogEntity();
				logEntity.Category = (int)LogCategory.SystemAction;
				logEntity.Message = string.Concat(new object[] { "模型ID 为", modelId, "的模型在修改", modelInfoById.TableName, "表的字段时产生错误！" });
				logEntity.ScriptName = "ModelsServiceAppDapper.cs";
				logEntity.Source = "m_repository.AddFieldToTable(fieldInfo, modelInfo.TableName)错误<br/>" + exception.Source;
				logEntity.Timestamp = DateTime.Now;
				logEntity.Title = "AddTableField方法出错";
				logEntity.UserName = "System";
				_LogRepository.Add(logEntity);
				return false;
			}
		}
		#endregion

		#region 修改
		/// <summary>
		/// 更新模型的字段。
		/// 1、更新字段到模型表(Models)。
		/// 2、更新字段到模型对应的扩展表中(只针对自定义字段并且字段类型为单行文本变多行文本的字段)。
		/// 3、删除缓存。
		/// </summary>
		/// <param name="fieldInfo"></param>
		/// <param name="modelType"></param>
		/// <returns></returns>
		public bool UpdateFieldOfTable(FieldInfo fieldInfo, ModelType modelType)
		{
			if (fieldInfo.FieldType == FieldType.FileType)
			{
				FieldInfo oldFieldInfo = GetFieldInfoByFieldName(modelType, fieldInfo.FieldName);
				if ((DataConverter.CBoolean(oldFieldInfo.Settings[3]) && !DataConverter.CBoolean(fieldInfo.Settings[3])) && !string.IsNullOrEmpty(fieldInfo.Settings[4]))
				{
					DeleteFieldToTable(fieldInfo.Settings[4], modelType);
					fieldInfo.Settings[4] = "";
				}
				if ((!DataConverter.CBoolean(oldFieldInfo.Settings[3]) && DataConverter.CBoolean(fieldInfo.Settings[3])) && !string.IsNullOrEmpty(fieldInfo.Settings[4]))
				{
					FieldInfo info2 = new FieldInfo();
					info2.Id = fieldInfo.Settings[4];
					info2.FieldName = fieldInfo.Settings[4];
					info2.FieldType = FieldType.TextType;
					info2.FieldLevel = 2;
					info2.OrderId = 0;
					ResultInfo resultInfo = AddFieldToTable(info2, modelType);
					if (resultInfo.Status==0)
					{
						return false;
					}
				}
			}
			IList<FieldInfo> fieldListByModelType = GetFieldListByModelType(modelType);
			FieldInfo oldField = null;
			foreach (FieldInfo info in fieldListByModelType)
			{
				if (info.Id == fieldInfo.Id)
				{
					oldField = info;
				}
			}
			fieldListByModelType.Remove(oldField);
			fieldListByModelType.Add(fieldInfo);
			string fieldList = fieldListByModelType.ToXml();
			bool flag = false;
			if (!UpdateField(modelType, fieldList))
			{
				return flag;
			}
			if (fieldInfo.FieldLevel == 0)
			{
				flag = true;
			}
			else
			{
				switch (fieldInfo.FieldType)
				{
					case FieldType.MultipleTextType:
					case FieldType.MultipleHtmlTextType:
					case FieldType.ContentType:
					case FieldType.MultiplePhotoType:
						flag = (oldField.FieldType != FieldType.TextType) || UpdateTableField(fieldInfo, modelType);
						break;
					default:
						flag = true;
						break;
				}
			}
			RemoveCache();
			return flag;
		}
		/// <summary>
		/// 更新模型的字段。
		/// 1、更新字段到模型表(Models)。
		/// 2、更新字段到模型对应的扩展表中(只针对自定义字段并且字段类型为单行文本变多行文本的字段)。
		/// 3、删除缓存。
		/// </summary>
		/// <param name="fieldInfo"></param>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool UpdateFieldOfTable(FieldInfo fieldInfo, int modelId)
		{
			if (fieldInfo.FieldType == FieldType.FileType)
			{
				FieldInfo oldFieldInfo = GetFieldInfoByFieldName(modelId, fieldInfo.FieldName);
				if ((DataConverter.CBoolean(oldFieldInfo.Settings[3]) && !DataConverter.CBoolean(fieldInfo.Settings[3])) && !string.IsNullOrEmpty(fieldInfo.Settings[4]))
				{
					DeleteFieldToTable(fieldInfo.Settings[4], modelId);
					fieldInfo.Settings[4] = "";
				}
				if ((!DataConverter.CBoolean(oldFieldInfo.Settings[3]) && DataConverter.CBoolean(fieldInfo.Settings[3])) && !string.IsNullOrEmpty(fieldInfo.Settings[4]))
				{
					FieldInfo info2 = new FieldInfo();
					info2.Id = fieldInfo.Settings[4];
					info2.FieldName = fieldInfo.Settings[4];
					info2.FieldType = FieldType.TextType;
					info2.FieldLevel = 2;
					info2.OrderId = 0;
					info2.Disabled = true;
					ResultInfo resultInfo = AddFieldToTable(info2, modelId);
					if (resultInfo.Status == 0)
					{
						return false;
					}
				}
			}
			IList<FieldInfo> fieldListByModelId = GetFieldListByModelId(modelId);
			FieldInfo oldField = null;
			foreach (FieldInfo info in fieldListByModelId)
			{
				if (info.Id == fieldInfo.Id)
				{
					oldField = info;
					break;
				}
			}
			fieldListByModelId.Remove(oldField);
			fieldListByModelId.Add(fieldInfo);
			string fieldList = fieldListByModelId.ToXml();
			bool flag = false;
			if (!UpdateField(modelId, fieldList))
			{
				return flag;
			}
			if (fieldInfo.FieldLevel == 0)
			{
				flag = true;
			}
			else
			{
				switch (fieldInfo.FieldType)
				{
					case FieldType.MultipleTextType:
					case FieldType.MultipleHtmlTextType:
					case FieldType.ContentType:
					case FieldType.MultiplePhotoType:
						flag = (oldField.FieldType != FieldType.TextType) || UpdateTableField(fieldInfo, modelId);
						break;
					case FieldType.ListBoxDataType:
						flag = UpdateTableField(fieldInfo, modelId);
						break;
					default:
						flag = true;
						break;
				}
			}
			RemoveCache();
			return flag;
		}

		/// <summary>
		/// 更新字段到模型扩展表中
		/// </summary>
		/// <param name="fieldInfo"></param>
		/// <param name="modelType"></param>
		/// <returns></returns>
		public bool UpdateTableField(FieldInfo fieldInfo, ModelType modelType)
		{
			var modelInfoByModelType = GetModelByModelType(modelType);
			try
			{
				m_repository.UpdateTableField(fieldInfo, modelInfoByModelType.TableName);
				RemoveCache();
				return true;
			}
			catch (DataException exception)
			{
				LogEntity logEntity = new LogEntity();
				logEntity.Category = (int)LogCategory.Exception;
				logEntity.Message = exception.Message;
				logEntity.Priority = (int)LogPriority.Low;
				logEntity.Source = exception.Source;
				logEntity.Timestamp = DateTime.Now;
				logEntity.Title = "更新" + modelInfoByModelType.ModelName + "模型的" + fieldInfo.FieldName + "字段出错！";
				logEntity.UserName = "System";
				_LogRepository.Add(logEntity);
				return false;
			}
		}
		/// <summary>
		/// 更新字段到模型扩展表中
		/// </summary>
		/// <param name="fieldInfo"></param>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool UpdateTableField(FieldInfo fieldInfo, int modelId)
		{
			var modelInfoById = Get(modelId);
			try
			{
				m_repository.UpdateTableField(fieldInfo, modelInfoById.TableName);
				RemoveCache();
				return true;
			}
			catch (DataException exception)
			{
				LogEntity logEntity = new LogEntity();
				logEntity.Category = (int)LogCategory.Exception;
				logEntity.Message = exception.Message;
				logEntity.Priority = (int)LogPriority.Low;
				logEntity.Source = exception.Source;
				logEntity.Timestamp = DateTime.Now;
				logEntity.Title = "更新" + modelInfoById.ModelName + "模型的" + fieldInfo.FieldName + "字段出错！";
				logEntity.UserName = "System";
				_LogRepository.Add(logEntity);
				return false;
			}
		}
		#endregion

		#region 删除
		/// <summary>
		/// 删除指定模型的字段，并删除相关信息。
		/// 1、系统级别（FieldLevel == 0）的字段不能删除。
		/// 2、字段类型为文件时，删除附属字段（保存文件大小的字段）。
		/// 3、更新字段信息到模型表。
		/// 4、删除相关信息(DeleteFieldPermissionFromGroup,DeleteFieldPermissionFromRoles)。
		/// 5、从模型扩展表中删除字段。
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="modelType"></param>
		/// <returns></returns>
		public bool DeleteFieldToTable(string fieldName, ModelType modelType)
		{
			fieldName = fieldName.ToLower();
			FieldInfo fieldInfoByFieldName = GetFieldInfoByFieldName(modelType, fieldName);
			if (fieldInfoByFieldName != null)
			{
				if (fieldInfoByFieldName.FieldLevel == 0)
				{
					return false;
				}
				if (((fieldInfoByFieldName.FieldType == FieldType.FileType) && !DataConverter.CBoolean(fieldInfoByFieldName.Settings[3])) && !string.IsNullOrEmpty(fieldInfoByFieldName.Settings[4]))
				{
					//删除文件类型的附属字段（保存文件大小的字段）
					DeleteFieldToTable(fieldInfoByFieldName.Settings[4], modelType);
				}
			}
			var modelInfoByModelType = GetModelByModelType(modelType);
			var manage = XmlHelper.Instance(modelInfoByModelType.Field, XmlType.Content);
			string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName + "\"]";
			manage.Remove(nodeName);
			if (!UpdateField(modelType, manage.Xml))
			{
				return false;
			}
			if ((fieldInfoByFieldName != null) && ((fieldInfoByFieldName.FieldType == FieldType.Property) || (fieldInfoByFieldName.FieldType == FieldType.ProductStyle)))
			{
				return true;
			}
			var modelsEntity = GetModelByModelType(modelType);
			_userGroupsServiceApp.DeleteFieldPermissionFromGroup(0,(int)modelsEntity.ModelID, fieldName,-1);
			_rolesServiceApp.DeleteFieldPermissionFromRoles(0, (int)modelsEntity.ModelID, fieldName);
			if (fieldInfoByFieldName.FieldType == FieldType.RegionType)
			{
				return DeleteTableRegionField(fieldName, modelInfoByModelType.TableName);
			}
			else if (fieldInfoByFieldName.FieldType == FieldType.RegionTypeFive)
			{
				return DeleteTableRegionFiveField(fieldName, modelInfoByModelType.TableName);
			}
			return DeleteTableField(fieldName, modelInfoByModelType.TableName);
		}
		/// <summary>
		/// 删除指定模型的字段，并删除相关信息。
		/// 1、系统级别（FieldLevel == 0）的字段不能删除。
		/// 2、字段类型为文件时，删除附属字段（保存文件大小的字段）。
		/// 3、更新字段信息到模型表。
		/// 4、删除相关信息(DeleteFieldPermissionFromGroup,DeleteFieldPermissionFromRoles)。
		/// 5、从模型扩展表中删除字段。
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool DeleteFieldToTable(string fieldName, int modelId)
		{
			fieldName = fieldName.ToLower();
			FieldInfo fieldInfoByFieldName = GetFieldInfoByFieldName(modelId, fieldName);
			if (fieldInfoByFieldName != null)
			{
				if (fieldInfoByFieldName.FieldLevel == 0)
				{
					return false;
				}
				if (((fieldInfoByFieldName.FieldType == FieldType.FileType) && DataConverter.CBoolean(fieldInfoByFieldName.Settings[3])) && !string.IsNullOrEmpty(fieldInfoByFieldName.Settings[4]))
				{
					DeleteFieldToTable(fieldInfoByFieldName.Settings[4], modelId);
				}
			}
			var modelInfoById = Get(modelId);
			XmlHelper manage = XmlHelper.Instance(modelInfoById.Field, XmlType.Content);
			string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName + "\"]";
			manage.Remove(nodeName);
			if (!UpdateField(modelId, manage.Xml))
			{
				return false;
			}
			if ((fieldInfoByFieldName != null) && ((fieldInfoByFieldName.FieldType == FieldType.Property) || (fieldInfoByFieldName.FieldType == FieldType.ProductStyle)))
			{
				return true;
			}
			_userGroupsServiceApp.DeleteFieldPermissionFromGroup(0, modelId, fieldName, -1);
			_rolesServiceApp.DeleteFieldPermissionFromRoles(0, modelId, fieldName);
			if (fieldInfoByFieldName.FieldType == FieldType.RegionType)
			{
				return DeleteTableRegionField(fieldName, modelInfoById.TableName);
			}
			else if (fieldInfoByFieldName.FieldType == FieldType.RegionTypeFive)
			{
				return DeleteTableRegionFiveField(fieldName, modelInfoById.TableName);
			}
			return DeleteTableField(fieldName, modelInfoById.TableName);
		}

		/// <summary>
		/// 从指定的模型扩展表中，移除指定字段列，失败则记录日志。
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="tableName"></param>
		/// <returns></returns>
		public bool DeleteTableField(string fieldName, string tableName)
		{
			try
			{
				m_repository.DeleteTableField(fieldName, tableName);
				RemoveCache();
				return true;
			}
			catch (Exception exception)
			{
				_LogRepository.SaveLog("删除" + tableName + "表的" + fieldName + "字段出错！", exception.Message, (string.IsNullOrEmpty(MyHttpContext.CurrentUserName)) ? "System" : MyHttpContext.CurrentUserName,
					LogCategory.Exception, LogPriority.Low, exception.Source, true);
				return false;
			}
		}
		/// <summary>
		/// 从指定模型扩展表中，移除指定行政区域字段列，失败则记录日志。
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="tableName"></param>
		/// <returns></returns>
		public bool DeleteTableRegionField(string fieldName, string tableName)
		{
			try
			{
				m_repository.DeleteTableRegionField(fieldName, tableName);
				RemoveCache();
				return true;
			}
			catch (Exception exception)
			{
				_LogRepository.SaveLog("删除" + tableName + "表的" + fieldName + "字段出错！", exception.Message, (string.IsNullOrEmpty(MyHttpContext.CurrentUserName)) ? "System" : MyHttpContext.CurrentUserName,
					LogCategory.Exception, LogPriority.Low, exception.Source, true);
				return false;
			}
		}
		/// <summary>
		/// 从指定模型扩展表中，移除指定行政区域(5级)字段列，失败则记录日志。
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="tableName"></param>
		/// <returns></returns>
		public bool DeleteTableRegionFiveField(string fieldName, string tableName)
		{
			try
			{
				m_repository.DeleteTableRegionFiveField(fieldName, tableName);
				RemoveCache();
				return true;
			}
			catch (Exception exception)
			{
				_LogRepository.SaveLog("删除" + tableName + "表的" + fieldName + "字段出错！", exception.Message, (string.IsNullOrEmpty(MyHttpContext.CurrentUserName)) ? "System" : MyHttpContext.CurrentUserName,
					LogCategory.Exception, LogPriority.Low, exception.Source, true);
				return false;
			}
		}
		#endregion

		#endregion

		#region 模型模板管理（表：ModelTemplates）
		/// <summary>
		/// 获取指定模板ID的字段列表(xml字符串)
		/// </summary>
		/// <param name="templateId"></param>
		/// <returns></returns>
		public string GetXmlFieldByTemplateId(int templateId)
		{
			string result = string.Empty;
			var templateEntity = _modelTemplatesRepository.Get(templateId);
			if (templateEntity != null)
			{
				result = templateEntity.Field;
			}
			return result;
		}
		/// <summary>
		/// 获取指定模板ID的字段列表
		/// </summary>
		/// <param name="templateId"></param>
		/// <returns></returns>
		public IList<FieldInfo> GetFieldListByTemplateId(int templateId)
		{
			List<FieldInfo> result = new List<FieldInfo>();
			var templateEntity = _modelTemplatesRepository.Get(templateId);
			if(templateEntity != null)
			{
				var xmlFieldList = templateEntity.Field;
				var list = xmlFieldList.ToXmlObject<List<FieldInfo>>();
				if (list != null && list.Count > 0)
				{
					list.Sort(new FieldInfoComparer());
					result = list;
				}
			}
			return result;
		}
		/// <summary>
		/// 得到模型模板中的字段
		/// </summary>
		/// <param name="templateId"></param>
		/// <param name="fieldName"></param>
		/// <returns></returns>
		public FieldInfo GetTemplatesFieldInfoByFieldName(int templateId, string fieldName)
		{
			var xmlFieldList = _modelTemplatesRepository.Get(templateId).Field;
			if (string.IsNullOrEmpty(xmlFieldList))
				return null;
			string xmlField = XmlHelper.Instance(xmlFieldList, XmlType.Content).SelectNode("/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]");
			return xmlField.ToXmlObject<FieldInfo>();
		}

		/// <summary>
		/// 更新模板字段列
		/// </summary>
		/// <param name="templateId"></param>
		/// <param name="fieldList">XML字段列表</param>
		/// <returns></returns>
		public bool UpdateTemplatesField(int templateId, string fieldList)
		{
			return _modelTemplatesRepository.Update("Field = @Field", " and TemplateID = @TemplateID", new { Field = fieldList, TemplateID = templateId });
		}
		/// <summary>
		/// 删除模型模板的字段
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="templateId"></param>
		/// <returns></returns>
		public bool DeleteTemplatesField(string fieldName, int templateId)
		{
			var templateInfoById = _modelTemplatesRepository.Get(templateId);
			if(templateInfoById == null || string.IsNullOrEmpty(templateInfoById.Field))
			{
				return false;
			}
			XmlHelper manage = XmlHelper.Instance(templateInfoById.Field, XmlType.Content);
			string xmlField = manage.SelectNode("/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]");
			FieldInfo fieldInfoByFieldName = xmlField.ToXmlObject<FieldInfo>();
			if (fieldInfoByFieldName != null)
			{
				if (fieldInfoByFieldName.FieldLevel == 0)
				{
					return false;
				}
				if (((fieldInfoByFieldName.FieldType == FieldType.FileType) && DataConverter.CBoolean(fieldInfoByFieldName.Settings[3])) && !string.IsNullOrEmpty(fieldInfoByFieldName.Settings[4]))
				{
					string nodeNameFileType = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldInfoByFieldName.Settings[4].ToLower() + "\"]";
					manage.Remove(nodeNameFileType);
				}
			}
			string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]";
			manage.Remove(nodeName);
			return UpdateTemplatesField(templateId, manage.Xml);
		}

		/// <summary>
		/// 禁用模型模板字段
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="disabled"></param>
		/// <param name="templateId"></param>
		/// <returns></returns>
		public bool SetTemplateFieldDisabled(string fieldName, bool disabled, int templateId)
		{
			return UpdateTemplatesField(templateId, SetFieldDisabled(fieldName, disabled, GetXmlFieldByTemplateId(templateId)));
		}

		/// <summary>
		///  模型模板字段必填
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="enable">true:必填；false:可空；</param>
		/// <param name="templateId"></param>
		/// <returns></returns>
		public bool SetTemplateFieldEnableNull(string fieldName, bool enable, int templateId)
		{
			return UpdateTemplatesField(templateId, SetFieldEnableNull(fieldName, enable, GetXmlFieldByTemplateId(templateId)));
		}

		/// <summary>
		///  模型模板字段允许搜索
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="enable">true:允许；false:不允许；</param>
		/// <param name="templateId"></param>
		/// <returns></returns>
		public bool SetTemplateFieldEnableSearch(string fieldName, bool enable, int templateId)
		{
			return UpdateTemplatesField(templateId, SetFieldEnableSearch(fieldName, enable, GetXmlFieldByTemplateId(templateId)));
		}

		/// <summary>
		/// 重设模型模板字段顺序
		/// </summary>
		/// <param name="fieldInfoList"></param>
		/// <param name="templateId"></param>
		/// <returns></returns>
		public bool SetTemplateOrderId(IList<FieldInfo> fieldInfoList, int templateId)
		{
			var manage = XmlHelper.Instance(GetXmlFieldByTemplateId(templateId), XmlType.Content);
			foreach (FieldInfo info in fieldInfoList)
			{
				string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + info.Id.ToLower() + "\"]";
				manage.SetAttributesValue(nodeName, "OrderId", info.OrderId.ToString());
			}
			return UpdateTemplatesField(templateId, manage.Xml);
		}
		/// <summary>
		/// 更新模型模板字段的顺序
		/// </summary>
		/// <param name="fieldName"></param>
		/// <param name="templateId"></param>
		/// <param name="orderId">排序号</param>
		/// <returns></returns>
		public bool SetTemplateOrderId(string fieldName, int templateId, int orderId)
		{
			var manage = XmlHelper.Instance(GetXmlFieldByTemplateId(templateId), XmlType.Content);
			string nodeName = "/ArrayOfFieldInfo/FieldInfo[@Id=\"" + fieldName.ToLower() + "\"]";
			manage.SetAttributesValue(nodeName, "OrderId", orderId.ToString());
			return UpdateTemplatesField(templateId, manage.Xml);
		}
		#endregion

		#region 节点模型模板管理（表：NodesModelTemplate）

		#region 是否存在数据
		/// <summary>
		/// 判断节点模型模板关系记录是否存在（表：NodesModelTemplate）
		/// </summary>
		/// <param name="nodeId"></param>
		/// <param name="modelId"></param>
		/// <returns></returns>
		public bool ModelIdExists(int nodeId, int modelId)
		{
			return _nodesModelTemplateRepository.IsExist(p => p.NodeID == nodeId && p.ModelID == modelId);
		}
		/// <summary>
		/// 判断节点模型模板关系记录是否存在（表：NodesModelTemplate）
		/// </summary>
		/// <param name="info"></param>
		/// <returns></returns>
		public bool ExistsNodesModelTemplateRelationShip(NodesModelTemplateEntity info)
		{
			return _nodesModelTemplateRepository.IsExist(p => p.NodeID == info.NodeID && p.ModelID == info.ModelID && p.DefaultTemplateFile == info.DefaultTemplateFile);
		}
		/// <summary>
		/// 判断节点模型模板关系记录是否存在（表：NodesModelTemplate）
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public bool ExistsNodesModelTemplateRelationShip(int nodeId)
		{
			return _nodesModelTemplateRepository.IsExist(p => p.NodeID == nodeId);
		}
		#endregion

		#region 得到实体类与实体类列表
		/// <summary>
		/// 获取节点模型模板关系列表
		/// </summary>
		/// <param name="nodeId"></param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<NodesModelTemplateEntity> GetNodesModelTemplateList(int nodeId, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return _nodesModelTemplateRepository.GetList(predicate: p => p.NodeID == nodeId, writeAndRead: writeAndRead).ToList();
		}
		#endregion

		#region 添加、修改、删除
		/// <summary>
		/// 为指定节点添加模型对应的默认模板，删除缓存。
		/// </summary>
		/// <param name="nodeId"></param>
		/// <param name="contentData">表结构：ModelID：模型ID；TemplateFile：默认模板文件路径；</param>
		/// <returns></returns>
		public bool AddModelForNodes(int nodeId, DataTable contentData)
		{
			bool flag = true;
			int count = contentData.Rows.Count;
			if (count == 0)
			{
				flag = false;
			}
			for (int i = 0; i < count; i++)
			{
				int modelId = DataConverter.CLng(contentData.Rows[i]["ModelID"]);
				string templateId = contentData.Rows[i]["TemplateFile"].ToString();
				if(ModelIdExists(nodeId, modelId))
				{
					continue;
				}
				NodesModelTemplateEntity entity = new NodesModelTemplateEntity();
				entity.NodeID = nodeId;
				entity.ModelID = modelId;
				entity.DefaultTemplateFile = templateId;
				if (!_nodesModelTemplateRepository.Add(entity))
				{
					flag = false;
					break;
				}
			}
			RemoveCache();
			return flag;
		}
		/// <summary>
		/// 添加节点-模型-模板关系，删除缓存。
		/// </summary>
		/// <param name="info"></param>
		/// <returns></returns>
		public bool AddNodesModelTemplateRelationShip(NodesModelTemplateEntity info)
		{
			bool flag = true;
			if ((!string.IsNullOrEmpty(info.DefaultTemplateFile) && (info.NodeID > 0)) && (info.ModelID > 0))
			{
				flag = _nodesModelTemplateRepository.Add(info);
			}
			RemoveCache();
			return flag;
		}
		/// <summary>
		/// 批量更新节点模型模板关系
		/// </summary>
		/// <param name="nodeId"></param>
		/// <param name="infoList"></param>
		/// <returns></returns>
		public bool UpdateNodesModelTemplateRelationShip(int nodeId, IList<NodesModelTemplateEntity> infoList)
		{
			bool flag = true;
			bool flag2 = true;
			if (ExistsNodesModelTemplateRelationShip(nodeId))
			{
				flag2 = DeleteNodesModelTemplateRelationShip(nodeId);
			}
			if (!flag2)
			{
				return false;
			}
			foreach (NodesModelTemplateEntity info in infoList)
			{
				info.NodeID = nodeId;
				flag = AddNodesModelTemplateRelationShip(info);
			}
			RemoveCache();
			return flag;
		}
		/// <summary>
		/// 删除节点-模型-模板关系(表：NodesModelTemplate)
		/// </summary>
		/// <param name="nodeId"></param>
		/// <returns></returns>
		public bool DeleteNodesModelTemplateRelationShip(int nodeId)
		{
			bool flag = _nodesModelTemplateRepository.Delete(p => p.NodeID == nodeId);
			if (flag)
			{
				RemoveCache();
			}
			return flag;
		}
		#endregion

		#endregion

		#region 为模型生成模板文件和内容页标签文件
		/// <summary>
		/// 为模型生成内容页标签文件（XSLT文件）。
		/// 保存目录：网站根目录//模板库目录/标签目录/模型名称
		/// </summary>
		/// <param name="modelId"></param>
		public void CreateIncludeField(int modelId)
		{
			var modelInfoById = GetCacheModelById(modelId);
			string path = FileHelper.ContentRootPath;
			IList<FieldInfo> fieldListByModelId = GetFieldListByModelId(modelId);
			CreateContentLabel(path, modelInfoById, fieldListByModelId);
		}
		/// <summary>
		/// 为模型生成内容页标签文件（XSLT文件）。
		/// 保存目录：网站根目录//模板库目录/标签目录/模型名称
		/// </summary>
		/// <param name="path">网站根目录物理路径</param>
		/// <param name="modelInfo"></param>
		/// <param name="fieldInfoList"></param>
		private void CreateContentLabel(string path, ModelsEntity modelInfo, IEnumerable<FieldInfo> fieldInfoList)
		{
			path = Utility.AppendTrailingSlash(path);
			string strLabelName = (modelInfo.ModelType == (int)ModelType.Shop) ? "商品_内容页.config" : "内容页.config";
			string pathLabel = path + "CommonTemplate/" + strLabelName;
			string LabelDir = Utility.AppendTrailingSlash(path + ConfigHelper.Get<SiteOptionConfig>().LabelDir);
			string ModelDir = Utility.AppendTrailingSlash(LabelDir + modelInfo.ModelName);
			string strLabelText;
			using (StreamReader reader = File.OpenText(pathLabel))
			{
				strLabelText = reader.ReadToEnd();
			}
			StringBuilder builder = new StringBuilder();
			foreach (FieldInfo info in fieldInfoList)
			{
				if ((info.FieldLevel != 1) || info.Disabled)
				{
					continue;
				}
				switch (info.FieldType)
				{
					case FieldType.MultipleHtmlTextType:
						{
							builder.Append("<" + info.FieldName + ">");
							builder.Append("<xsl:value-of disable-output-escaping=\"yes\" select=\"/NewDataSet/Table/" + info.FieldName + "\"/>");
							builder.Append("</" + info.FieldName + ">");
							continue;
						}
					case FieldType.MoneyType:
						{
							builder.Append("<" + info.FieldName + ">");
							builder.Append("￥<xsl:value-of disable-output-escaping=\"yes\" select=\"format-number(/NewDataSet/Table/" + info.FieldName + ",'0.00')\"/>");
							builder.Append("</" + info.FieldName + ">");
							continue;
						}
					case FieldType.DateTimeType:
						{
							builder.Append("<" + info.FieldName + ">");
							builder.Append("<xsl:value-of select=\"jx:FormatDate(/NewDataSet/Table/" + info.FieldName + ",'yyyy-mm-dd')\"/>");
							builder.Append("</" + info.FieldName + ">");
							continue;
						}
					case FieldType.LinkType:
						{
							builder.Append("<" + info.FieldName + ">");
							builder.Append("<a> <xsl:attribute name=\"href\"><xsl:value-of select=\"/NewDataSet/Table/" + info.FieldName + "\"/></xsl:attribute></a>");
							builder.Append("</" + info.FieldName + ">");
							continue;
						}
					case FieldType.BoolType:
						{
							builder.Append("<" + info.FieldName + ">");
							builder.Append("<xsl:choose><xsl:when test=\"/NewDataSet/Table/" + info.FieldName + "='true'\">是</xsl:when><xsl:otherwise>否</xsl:otherwise></xsl:choose>");
							builder.Append("</" + info.FieldName + ">");
							continue;
						}
					case FieldType.PictureType:
						{
							builder.Append("<" + info.FieldName + ">");
							builder.Append("<xsl:element name=\"img\"><xsl:attribute name=\"src\"><xsl:value-of select=\"jx:UpLoadDir()\"/><xsl:value-of select=\"/NewDataSet/Table/" + info.FieldName + "\"/></xsl:attribute></xsl:element>");
							builder.Append("</" + info.FieldName + ">");
							continue;
						}
				}
				builder.Append("<" + info.FieldName + ">");
				builder.Append("<xsl:value-of select=\"/NewDataSet/Table/" + info.FieldName + "\"/>");
				builder.Append("</" + info.FieldName + ">");
			}
			strLabelText = strLabelText.Replace("{JX.TemplateCreator.TableName}", modelInfo.TableName)
				.Replace("{JX.TemplateCreator.ItemName}", modelInfo.ItemName)
				.Replace("{JX.TemplateCreator.ModelName}", modelInfo.ModelName)
				.Replace("{JX.TemplateCreator.ModelID}", modelInfo.ModelID.ToString())
				.Replace("{JX.TemplateCreator.Custom}", builder.ToString());
			if (modelInfo.ModelType == (int)(ModelType.Shop))
			{
				FileHelper.WriteFile(ModelDir + modelInfo.ModelName + "_商品_内容页.config", strLabelText);
			}
			else
			{
				FileHelper.WriteFile(ModelDir + modelInfo.ModelName + "_内容页.config", strLabelText);
			}
		}
		/// <summary>
		/// 为模型生成通用内容列表页模板:保存在:网站根目录/CommonTemplate/templateName/modelInfo.ModelName_templateName目录下。
		/// 内容为：《tr》《td》{JX.Field id=\"cone\" fieldname=\"" + info.FieldName + "\" /}《/td》《/tr》
		/// </summary>
		/// <param name="modelId"></param>
		/// <param name="templateName"></param>
		public void CreateIncludeModel(int modelId, string templateName)
		{
			var modelInfoById = GetCacheModelById(modelId);
			CreateCommonListPageTemplate(modelInfoById, (ModelType)modelInfoById.ModelType, templateName);
		}
		/// <summary>
		/// 为模型生成模板文件。保存目录：网站根目录/模板目录/模型名称/文件名
		/// </summary>
		/// <param name="modelInfo"></param>
		/// <param name="modelType"></param>
		/// <param name="templateName"></param>
		private void CreateCommonListPageTemplate(ModelsEntity modelInfo, ModelType modelType, string templateName)
		{
			if (modelType != ModelType.CustomForm)
			{
				IList<FieldInfo> fieldListByModelId = GetFieldListByXmlField(modelInfo.Field);
				string virtualPath = FileHelper.ContentRootPath;
				StringBuilder builder = new StringBuilder();
				foreach (FieldInfo info in fieldListByModelId)
				{
					if ((info.FieldLevel == 1) && !info.Disabled)
					{
						builder.Append("<tr><td>{JX.Field id=\"cone\" fieldname=\"" + info.FieldName + "\" /}</td></tr>");
					}
				}
				string fileContent = FileHelper.ReadFile(Utility.AppendTrailingSlash(virtualPath) + "CommonTemplate/" + templateName)
					.Replace("{JX.TemplateCreator.TableName}", modelInfo.TableName)
					.Replace("{JX.TemplateCreator.ModelName}", modelInfo.ModelName)
					.Replace("{JX.TemplateCreator.ItemName}", modelInfo.ItemName)
					.Replace("{JX.TemplateCreator.ModelID}", modelInfo.ModelID.ToString())
					.Replace("{JX.TemplateCreator.Custom}", builder.ToString())
					.Replace("{JX.TemplateCreator.ContentLabelName}", modelInfo.ModelName + "_内容页");
				string str4 = Utility.AppendTrailingSlash(virtualPath) + Utility.AppendTrailingSlash(ConfigHelper.Get<SiteOptionConfig>().TemplateDir) + modelInfo.ModelName;
				FileHelper.WriteFile(str4 + "/" + modelInfo.ModelName + "_" + templateName, fileContent);
			}
		}
		#endregion

		#region 其他
		/// <summary>
		/// 在指定表中查找指定字段的值列表，如果表名为“CommonInfo”，需要指定modelId
		/// </summary>
		/// <param name="tableName">模型表名</param>
		/// <param name="fieldName">模型字段名</param>
		/// <param name="modelId">模型ID</param>
		/// <param name="writeAndRead"></param>
		/// <returns></returns>
		public IList<string> GetLookupField(string tableName, string fieldName, int modelId, WriteAndReadEnum writeAndRead = WriteAndReadEnum.None)
		{
			return m_repository.GetLookupField(tableName, fieldName, modelId, writeAndRead);
		}
		/// <summary>
		/// 得到已启用的、模型类型为内容模型的ModelID集合。多个ID用“,”分割
		/// </summary>
		/// <returns></returns>
		public string GetCacheContentModelIdList()
		{
			string str = CacheHelper.CacheServiceProvider.Get("CK_CommonModel_String_ModelIdArr_Content") as string;
			if (string.IsNullOrEmpty(str))
			{
				StringBuilder builder = new StringBuilder();
				foreach (var info in GetModelList(ModelType.Content, ModelShowType.Enable))
				{
					StringHelper.AppendString(builder, info.ModelID.ToString());
				}
				str = builder.ToString();
				CacheHelper.CacheServiceProvider.AddOrUpdate("CK_CommonModel_String_ModelIdArr_Content", str,TimeSpan.FromDays(1));
			}
			return str;
		}
		/// <summary>
		/// 获取启用的商品模型所对应绑定的第一个节点ID。返回值格式：(模型ID,节点ID)
		/// </summary>
		/// <returns></returns>
		public string GetNodeIdModelIdByShopModelType()
		{
			int modelId = 0;
			int nodeId = 0;
			bool flag = false;
			bool flag2 = false;
			foreach (var info in GetModelList(ModelType.Shop, ModelShowType.Enable))
			{
				if (flag)
				{
					break;
				}
				var nodesModelTemplateList = _nodesModelTemplateRepository.GetList(p => p.ModelID == info.ModelID);
				if (nodesModelTemplateList.Count() > 0)
				{
					modelId = (int)info.ModelID;
					foreach (var info2 in nodesModelTemplateList)
					{
						if (flag2)
						{
							break;
						}
						nodeId = (int)info2.NodeID;
						if (nodeId > 0)
						{
							flag2 = true;
						}
					}
					flag = true;
				}
			}
			return (modelId + "," + nodeId).ToString();
		}

		/// <summary>
		/// 删除模型缓存
		/// </summary>
		public void RemoveCache()
		{
			CacheHelper.CacheServiceProvider.RemoveCacheRegex(@"CK_CommonModel_\S*");
		}
		#endregion
	}
}